Java 파트6-3. 생성자

1. 시작하기 전에


  • 생성자 : 클래스로부터 new 연산자로 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.
    • 생성자는 new 연산자로 호출되는 중괄호{} 블록이다.
  • 객체 초기화 : 필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 하는 것
  • 생성자가 성공적으로 실행 시 힙 영역에 객체가 생성되고 객체의 번지가 리턴

그림1


2. 기본 생성자


클래스 내부에 생성자 선언을 생략할 경우 바이트 코드에 자동 추가된다. 따라서 클래스에 생성자를 선언하지 않아도 new 생성자()로 객체 생성이 가능하다.

클래스명() {} 

클래스 선언할  만약 public class 클래스명 {} 으로 public이 붙어있다면
생성자에도 아래와 같이 public이 자동으로 추가된다.
public 클래스() {}

그림2


3. 선언


클래스에 생성자가 명시적으로 선언되었을 경우 반드시 선언된 생성자를 호출하여 객체를 생성해야 한다. (매개변수도 만족하도록)

클래스명(매개변수선언){ // 매개변수선언은 생략할 수도 여러 개를 선언할 수도 있음
    // 객체의 초기화 코드
}

4. 생성자의 필드 초기화


public class Korean{
    // 필드
    String nation = "Korea";
    String name;
    int age;

    // 생성자
    public Korean(String n, int a){
        name = n;
        age = a;
    }
}

main 에서
Korean k1 = new Korean("홍길동",23);
Korean k2 = new Korean("장보고",25);

nation은 고정값으로 굳이 인자도 받지 않아도 되므로 필드값으로 주었고 이름과 나이는 사람마다 다르므로 생성자의 인자로 받아 대입시켰다. 이런식으로 활용하는 것이다.
메인에서 위와 같이 선언하게 되면 스택에는 k1,k2가 생성되고 힙에는 객체 2개가 생성된다. 이 객체의 주소를 k1,k2가 받으면서 참조하게 된다.

필드 초기화 주의점

  • 생성자의 인자로 사용하는 매개 변수 이름은 필드 이름과 유사하거나 동일한 것으로 사용을 권장한다.
  • 필드와 매개 변수 이름이 완전히 동일한 경우 this.필드명 으로 표현한다.
public class Korean{
    // 필드
    String nation = "Korea";
    String name;
    int age;

    // 생성자
    public Korean(String name, int age){
        name = name;
        age = age;
    }
}

public class Korean{
    // 필드
    String nation = "Korea";
    String name;
    int age;

    // 생성자
    public Korean(String name, int age){
        this.name = name;
        this.age = age;
    }
}

위 코드에서 보면 생성자의 인자와 클래스 필드의 변수명이 같다. 이 경우에는 클래스의 필드보다 매개인자가 우선적으로 사용된다. 따라서 인자 name에 인자 name을 넣는 적절하지 못한 동작이 수행된다. 따라서 이를 방지하기 위해 this. 을 사용한다. this.은 내가 가지고 있는 이라고 해석하면 된다. 따라서 this.name은 내가 가지고 있는 필드 name을 의미하게 된다.


5. 생성자 오버로딩


  • 매개 변수를 달리하는 생성자를 여러 개 선언하는 것을 의미
  • 외부에서 제공되는 다양한 데이터 사용하여 객체 초기화하려면 생성자 역시 다양화해야하기 때문에 사용한다.
public class Car{
    Car(){..}
    Car(String model){...}
    Car(String model, String color){...}
    Car(String model, String color, int maxspeed){...}

    Car(String mo,int x) // 오버로딩이 아님
    Car(String de,int y) // 오버로딩이 아님
}

매개 변수의 타입, 개수, 선언된 순서가 같은 경우, 매개 변수 이름만 바꾸는 것은 오버로딩이 아니다.

6. 다른 생성자 호출: this()


  • 생성자에서 다른 생성자 호출
  • 필드 초기화 내용을 한 생성자에만 집중 작성하고 나머지 생성자는 초기화 내용을 가진 생성자로 호출한다.
    • 생성자 오버로딩 증가 시 중복 코드 발생 문제를 해결
  • 생성자 첫 줄에서만 허용한다. 만약 첫 줄에 출력을 찍고 다음에 this호출시 에러가 뜬다.
// 생성자 오버로딩으로 인한 중복 코드 발생
public class Car{
    // 필드 있다고 가정
    
    Car(String model){
        this.model = model;
        this.color = "은색";
        this.maxspeed = 250; 
    }

    Car(String model, String color){
        this.model = model;
        this.color = color;
        this.maxspeed = 250; 
    }

    Car(String model, String color, int maxspeed){
        this.model = model;
        this.color = color;
        this.maxspeed = speed; 
    }
}

// 다른 생성자 호출로 해결
public class Car{
    // 필드 있다고 가정
    
    Car(String model){
        this(model,"은색",250); // 해당 인자를 소화할 수 있는 생성자를 호출, 즉 3번째 호출
    }

    Car(String model, String color){ // 해당 인자를 소화할 수 있는 생성자를 호출, 즉 3번째 호출
        this(model,color,250)
    }

    Car(String model, String color, int maxspeed){
        this.model = model;
        this.color = color;
        this.maxspeed = speed; 
    }
}


7. 정리하기


  • 기본 생성자 : 클래스 선언 시 컴파일러에 의해 자동으로 추가되는 생성자
  • 생성자 선언 : 생성자를 명시적으로 선언 가능, 생성자를 선언하면 기본 생성자는 생성되지 않음
  • 매개 변수 : 생성자 호출 시 값을 전달받기 위해 선언되는 변수
  • 객체 초기화 : 생성자 내부에서 필드값 초기화하거나 메소드 호출해서 사용 준비를 하는 것
  • 오버로딩 : 매개 변수를 달리하는 생성자를 여러 개 선언
  • this() : 객체 자신의 또다른 생성자를 호출할 때 사용



© 2021. By Backtony