JAVA

생성자(Constructor), this

HipPopoTamUs 2022. 8. 2. 21:41

생성자란?

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메소드

생성자의 이름은 클래스의 이름과 같아야 하며, 리턴값이 없다.

모든 생성자는 리턴값이 없기 때문에 선언부 앞에 void를 적지 않는다.

 

또한 생성자도 오버로딩이 가능하므로 하나의 클래스에 여러개의 생성자를 만들 수 있다.

모든 클래스에는 반드시 하나 이상의 생성자가 있어야 하는데, 별도로 생성자를 

만들지 않았을 시엔 컴파일러가 기본 생성자를 자동으로 추가한다.

 

기본 생성자는 '클래스명() {}' 과 같이 매개변수도 없고 내용도 없는 생성자이다.

매개변수가 있는 생성자를 만들었을 때는 인스턴스를 생성함과 동시에

인스턴스 변수를 원하는 값으로 초기화할 수 있기 때문에 더 간결하고 편리하다.

class Car{
	//인스턴스 변수들
    String color;
    String gear;
    int door;
    
    Car() {
        this(color,gear,door);
 //     Car(color,gear,door);	-> 오류
    }
    Car(String color, String gear, int door){
    	this.color = color;
        this.gear = gear;
        this.door = door;
    }
}

생성자에서 다른 생성자 호출하기 - this 이용

생성자 내에서 다른 생성자를 호출할 때에는 생성자명을 쓰는 것이 아닌

1. this를 사용해야한다. 

2. 생성자 블럭 내부의 첫 줄에서 호출해야한다.

보통 생성자 내에서는 인스턴스 변수의 초기화가 이루어지는데, 첫 줄이 아닌 중간쯤에서 다른 생성자를 호출하면

새로 호출된 생성자 내에서도 인스턴스 변수를 초기화하므로, 처음 호출했던 생성자에서 초기화했던 것이

무용지물이 된다. 따라서 다른 생성자를 호출할 때에는 인스턴스 변수를 초기화 하기 전인 첫번째 줄에 호출한다. 

 

this는 인스턴스 자신의 주소를 담고있는 참조변수이다. 클래스의 인스턴스를 다루려면 참조변수가 꼭 있어야하듯이,

this로 자신의 인스턴스 변수를 다룰 수 있다. 그러나 this는 static변수는 다룰 수 없다.

모든 인스턴스 메소드에는 자신이 속한 인스턴스의 주소가 지역변수로 저장되어있다. (보이진않음)

이 지역변수가 바로 this이다.

** this()는 생성자이고 this는 참조변수이다. 이 둘은 엄연히 다르다. **

 

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

두 인스턴스의 상태가 같다는 것은 인스턴스 변수의 값이 서로 같다는 것을 의미한다. 

메소드는 기능이기 때문에 모든 인스턴스에서 같고, 클래스 변수는 인스턴스 별 공통된 메모리를 공유하기 때문에 다를 수 없다.

따라서 상태가 같다는 것은 인스턴스 변수의 값이 같다는 것을 의미한다.

 

만약 한 인스턴스를 생성하고 이와 같은 상태의 인스턴스가 하나 더 필요하다고 가정해보자.

이때 일일이 복사하고 싶은 인스턴스 변수의 값을 알아낼 필요없이, 생성자의 매개변수에

인스턴스 참조변수를 전달하면 편리하게 복사할 수 있다.

class Car{
    String color;
    String gear;
    int door;
    
    Car() {
    	this("white","auto",4);		//다른 생성자 호출
    }
    
    Car(Car c){		//다른 인스턴스를 복사하고 싶을 때 쓰는 생성자
    	color = c.color;
        gear = c.gear;
        door = c.door;
        // this(c.color, c.gear, c.door); 이 더 간결하다.
    }
    
    Car(String color, String gear, int door){
    	this.color = color;
        this.gear = gear;
        this.door = door;
    }
}

class CarTest{
    public static void main(String[] args){
        Car car1 = new Car();	// ...(ㄱ)
        Car car2 = new Car(car1);	// ...(ㄴ)
    }
}

(ㄱ)에서 속성이 white, auto, 4인 인스턴스를 참조하는 변수 car1을 만들었다.

(ㄴ)에서는 생성자 인수에 참조변수 car1을 넣어 car1의 속성을 복사한 인스턴스를 만들었다.

 

이후 car1.color = "red";와 같이 car1의 속성을 변경해도 car2는 "white" 그대로이다.

car2가 car1을 참조한 것이 아니라, 생성할 때 단지 car1의 속성을 복사해서 만든 것일 뿐이기 때문이다.