본문 바로가기

Java/자바의 정석 3판

객체지향 프로그래밍(1) - 생성자(Constructor)

생성자(Constructor)

인스턴스 생성 시, 호출되는 '인스턴스 초기화 메서드'

생성자는 오버로딩의 대표적인 예로, 생성자 오버로딩이라 불리기도 한다.

Car c = new Car();
Car c = new Car("white","auto",4);

인스턴스 생성 단계는 다음과 같다.

 

  1. 연산자 new에 의해서 메모리(heap 영역)에 Car 클래스의 인스턴스 생성.
  2. 생성자 Car()가 호출되어 인스턴스 초기화.
  3. 생성된 Car 인스턴스의 주소가 참조변수 c에 저장.

 

기본 생성자가 아닌 매개변수가 있는 생성자를 정의하고, 호출하여 인스턴스 내 변수의 값을 원하는 대로 초기화 할 수도 있다.

 

생성자의 특징은 생성자의 이름이 클래스명과 같아야하며, 리턴 값이 따로 없다는 것이다.

보통은 리턴 값이 없을 때 메서드 앞에 리턴타입 void를 붙이지만, 생성자는 리턴 값이 존재하지 않기 때문에 생략이 가능하다.

 

class Car{
	String color;
	String gearType;
	int door;
    
    Car(){
    	//super();
    	// 생성자를 정의하지 않았을 경우 
        // 컴파일러가 자동적으로 기본 생성자를 추가한다.
        
        // 클래스에 생성자가 존재할 경우, 
        // 자동으로 추가되지 않기 때문에 주의해야한다. 
	}
    Car(String color, String gearType, int door){
    	this.color = color;
        this.gearType = gearType;
        this.door = door;
        // 매개변수가 있는 생성자. 
        // 원하는 대로 생성된 인스턴스의 값을 설정할 수 있다.
    }
}

기본 생성자의 경우, 클래스에 생성자가 존재하는 경우 자동으로 생성되지 않는다.

무심코 생성자를 정의해두고서는 인스턴스를 생성할 때 기본 생성자를 호출할 경우, 에러가 발생할 수 있다.

따라서, 기본 생성자를 정의해두는 습관을 기르는 것이 좋다. 

 

부모 클래스의 생성자 super()

생성자는 첫 줄에 무조건 다른 생성자를 호출한다.

생성자가 정의되어 있지 않을 경우, 컴파일러는 super(); 코드를 추가하여 부모의 생성자를 호출한다.

최종적으로 가장 상위에 있는 Object 클래스의 생성자에 도달하기 전까지 해당 작업을 계속한다.

 

부모 클래스의 생성자를 호출하는 super()를 통해서, 부모 클래스에 있는 멤버 변수를 초기화 하도록

사용할 수도 있다.

 

생성자 this()

생성자에서 같은 클래스의 다른 생성자를 호출할 수도 있다.

단, 생성자의 첫줄에서만 호출이 가능하기 때문에 이 점에 주의한다.

(이러한 속성에는 부모 클래스의 생성자를 호출하는 super() 와 관련이 있지만 후술하도록 하겠다.)

class Car{
	String color;
	String gearType;
	int door;

    Car(){
    	this("white","auto","4");
	}
    Car(String color){
    	this(color,"auto",4);
    }
    Car(String color, String gearType, int door){
    	this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}

생성자가 다른 생성자를 호출할 수 있는 점을 이용해서, 좀 더 유기적으로 코드를 작성할 수 있다.

 

인스턴스 변수와 지역 변수의 이름이 같을 경우, 참조변수 this를 사용하여 구분지을 수 있다.

참조 변수 this는 인스턴스 자신을 가리키며, 인스턴스의 주소가 저장되어있다.

 

 

생성자를 이용한 인스턴스의 복사

Car c1 = new Car();
Car c2 = new Car(c1);
class Car{
	String color;
	String gearType;
	int door;
    
    Car(Car c){
    	this.color = c.color;
        this.gearType = c.gearType;
        this.door = c.door;
    }
}

위처럼 생성자를 호출할 때, 인자로 클래스의 참조변수를 받아와 사용할 수도 있다.

해당 코드로 인스턴스를 생성하면, c1 인스턴스에 저장된 인스턴수 변수들의 값을 그대로 복사해 올 수 있다.