[Java] 2-2. 메서드(Method) / 생성자(Constructor)

루키·2024년 7월 25일

Java

목록 보기
8/10
post-thumbnail

1. Method란?

1-1. 메서드란?

  • 메서드란? : 현실의 객체가 하는 동작을 프로그래밍화한 것입니다.

  • 메서드를 작성하는 이유

    • 반복적으로 사용되는 코드의 중복을 방지합니다.
    • 코드의 양을 줄일 수 있고, 유지 보수가 용이합니다.
  • 메서드 작성 방법

    <제한자> <리턴 타입> <메서드명> ([<파라미터>타입 변수명],...) // 선언부
    {
      // 구현부
    }
    • 리턴 타입 : 메서드를 호출한 곳으로 반환되는 값의 타입으로 아무것도 리턴하지 않을 경우 void를 사용합니다.

    • 파라미터 : 메서드 호출 시점에 넘겨줘야하는 변수들로 넘겨줄 정보가 없을 경우 생략 가능합니다.
      cf) 메서드 선언 시 동일 타입의 인자가 몇 개가 들어올 지 예상할 수 없거나 가변적일 경우, ... 기호를 활용해서 여러 개의 파라미터를 넘겨줄 수 있습니다.
      EX)

      class VariableTest{
          public void addAll(int ...params) {
              int sum = 0;
              for(int i : params) // params는 배열과 같은 형태로 받아옴
              { sum += i; }
              System.out.println(sum);
      
          }
      }
      
      public class Main {
          public static void main(String[] args) {
              VariableTest vt = new VariableTest();
              vt.addAll(1,2,3);       // 6
              vt.addAll(1,2,3,4,5);   // 15
              vt.addAll(1,2);         // 3
          }
      }
  • 메서드 활용 예시

    class Person {
        String name;
        int age = 0;
        
        void toString(){
            System.out.println(name+" : "+age);
        }
    }
    
    // 메서드를 사용하지 않을 경우
    Person p1 = new Person();
    System.out.println(p1.name+" : "+p1.age);
    Person p2 = new Person();
    System.out.println(p2.name+" : "+p2.age);
    
    // 메서드를 사용할 경우
    Person p1 = new Person();
    Person p2 = new Person();
    p1.toString();
    p2.toString();

    메서드를 사용하지 않으면 객체의 데이터에 직접 접근 해야하고, 멤버 변수가 바뀌거나 한다면 따로따로 수정해줘야하는 불편함이 있습니다. 하지만 메서드를 사용하면 main함수의 코드가 간결해지고, 모듈화가 되어있기 때문에 객체에서만 변경해주면 모든 코드에 적용할 수 있습니다.

1-2. 메서드 호출하기

  • 메서드 호출 : 메서드의 선언부에 맞춰서 이름과 파라미터 갯수를 동일하게 호출합니다.

  • 메서드 접근 : 멤버 변수와 마찬가지로 static 또는 non static 상태를 구분해서 호출합니다.

    비고static memberinstance member
    소속클래스객체
    같은 클래스바로 호출바로 호출
    다른 클래스클래스이름.멤버이름(객체 생성 후)객체이름.멤버이름
    • class 멤버와 instance 멤버간 참조와 호출 : 멤버가 메모리에 있어야 호출 가능
      • static member(클래스 멤버) : 항상 메모리에 있음 - 클래스 로딩 시 자동 등록
      • instance member(인스턴스 멤버) : 객체 생성 전에는 메모리에 없음, 객체 생성 후 레퍼런스를 통해서 접근 가능
    • 기본형 변수와 참조형 변수
      • 메서드 호출 시, 기본형 변수를 파라미터로 전달하게 되면, 메서드 동작이 종료되어도 값이 변하지 않습니다.
      • 대신 참조형 변수를 파라미터로 전달하게 되면, 메서드 동작이 종료되어도 참조하고 있던 변수의 값이 변경됩니다.
  • 메서드 호출 스택 : 각각 메서드 호출 시 마다 메서드 동작을 위한 메모리를 쌓음

    • Stack(스택) : Last in First Out(LIFO) 구조
    • 스택 아래에 있는 메모리는 사라지는 것이 아니라 일시 정지 상태로 대기합니다.
    • 메서드 동작이 끝나서 메모리에서 제거되면 아래에 있는 메모리에 있는 메서드가 다시 동작합니다.

1-3. Method Overloading(메서드 오버로딩)

  • Overloading : 동일한 기능을 수행하는 메서드의 추가 작성할 때 사용합니다.

    동일한 기능을 여러 형태로 정의할 때 사용됩니다.

    • 장점 : 기억해야할 메서드가 감소하고 중복 코드에 대해 효율적 관리가 가능합니다.
  • 활용 방법

    • 메서드 이름은 동일 , 파라미터의 개수 또는 순서, 타입이 달라야합니다.
    EX)
    // 주어진 파라미터를 더하는 메서드 구현
    
    // 파라미터 이름만 다를 경우
    int add(int a, int b) {return a + b;}
    int add(int x, int y) {return x + y;} // 오류
    
    // 리턴 타입이 다른 경우
    int add(int a, int b) {return a + b;}
    long add(int a, int b) {return a + b;} // 오류
    
    // 파라미터의 타입이 다른 경우
    int add(int a, int b) {return a + b;}
    long add(long a, long b) {return a + b;} // 메서드 오버로딩
    
    // 파라미터의 수가 다른 경우
    int add(int a, int b) {return a + b;}
    int add(int a, int b, int c) {return a + b + c;} // 메서드 오버로딩

2. Constructor란?

2-1. 생성자란?

  • 생성자란? : 객체를 생성할 때 사용하는 것으로 메서드와 비슷합니다.
  • 생성자 작성 규칙 : 이름은 클래스와 동일하게 사용하며 메서드와 다르게 리턴타입이 없습니다.
    <제한자> <클래스명>([인자]) {
        // 맴버 변수 초기화 작업
    }
  • 생성자 호출 방법 : 객체를 생성할 때 new 키워드를 사용해서 호출합니다.
  • 생성자의 종류
    • 기본 생성자 (default constructor) : 기본 생성자의 형태는 파라미터가 없고, 구현부가 비어있는 형태입니다.
    public DefaultConstructor() { }
    • 파라미터가 있는 생성자 : 생성자 호출시 값을 넘겨주며 일반 멤버 변수를 초기화합니다. (* 파라미터가 있는 생성자를 만들면 기본 생성자는 추가되지 않습니다.)
    public ParameterConstructor() {
        <멤버 변수> = <>
    }

2-2. this의 용법

  • this : 참조 변수로 객체 자신을 가리키는 키워드입니다. 참조 변수를 통해 객체의 멤버에 접근했던 것 처럼 this를 이용해 자신의 멤버에 접근이 가능합니다.
public class Person {
    String name;
    int age;
    
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
  • 용도 : 로컬 변수와 멤버 변수의 이름이 동일할 경우 멤버 변수임을 명시적으로 나타냅니다.

this는 객체에 대한 참조이기 때문에 static 영역에서는 사용이 불가능합니다.

  • this 오버로딩 : 메서드와 마찬가지로 생성자도 오버로딩이 가능합니다.
    • 객체 생성 시 필요한 멤버 변수만 초기화 진행한다면 생성자 별 코드의 중복이 발생합니다.
    • 이를 해결하기 위해 this() 키워드를 사용하여 생성자를 오버로딩 할 수 있습니다.
    public class Person {
        String name;
        int age;
        
        Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        Person(String name) { // 생성자 오버로딩
            this(name, 0);
        }
        
        Person() { // 생성자 오버로딩
            this("루키", 25);
        }
    }

2-3. 초기화(Initializer) 블록

  • 초기화 블록 : 생성자처럼 멤버 변수의 초기화를 목적으로 합니다.
    • 클래스 초기화 블록 : 클래스 멤버 변수를 초기화하며, 클래스 로딩 시 1회만 호출됩니다.
    • 인스턴스 초기화 블록 : 인스턴스 멤버 변수를 초기화하며, 객체 생성시 마다 1회 호출됩니다. 생성자의 내부 코드보다 먼저 실행됩니다.
public class InitializerTest {
	int iv;
	static int cv;
	
	
	///--1--//////////////////////////////////////
	static {
		System.out.println("static Initializer");
		cv = 100;
	}
	
	///--4--////////////Initializer///////////////
	{
		System.out.println("instance initializer");
		iv = 100;
	}
	
	///--3--//////////////////////////////////////
	public InitializerTest() {
		System.out.printf("생성자 - iv : %d, cv : %d\n", iv, cv);
		this.iv = 300;
	}
	
    ///--2--//////////////////////////////////////
	public static void main(String args[]) {
		System.out.println();
		InitializerTest it = new InitializerTest(); // --> 3 --> 4 실행
		System.out.printf("1 - iv : %d, cv : %d\n", it.iv, cv);
		InitializerTest it2 = new InitializerTest(); // --> 3 --> 4 실행
		System.out.printf("2 - iv : %d, cv : %d\n", it2.iv, cv);
	}
    //////////////////////////////////////////////
}

// 실행 결과 (1 -> 2 -> 3 -> 4)
//
// static Initializer
//
// instance initializer
// 셍성자 - iv : 100, cv : 100
// 1 - iv : 300, cv : 100
// instance initializer
// 셍성자 - iv : 100, cv : 100
// 2 - iv : 300, cv : 100
profile
주니어 FrontEnd 개발자가 되기 위한 기록

0개의 댓글