자바 (ref. 자바의정석)

생성자 (Constructor) - JAVA

쿠쿠s 2022. 2. 15. 12:39

 

 

생성자란?

 

생성자는 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드' 입니다.

인스턴스 변수의 초기화 작업에 주로 사용되며, 인스턴스 생성 시에 반드시 실행 되어야 할 작업을 위해서도 사용됩니다.

연산자 new가 인스턴스를 생성하는 것이지 생성자가 인스턴스를 생성하는 것은 아닙니다.

 

 

 

 

그러면 생성자는 어떻게 만드는 것일까? 다음과 같은 조건이 있습니다.

1. 생성자의 이름은 클래스의 이름과 같아야 한다.
2. 생성자는 리턴 값이 없다.

 

 

 

 

추가로 생성자도 오버로딩이 가능하므로 여러 생성자가 존재하게 만들 수 있습니다.

 

public class ConstructorEx {

    public static void main(String[] args) {
        Car k3 = new Car();
        Car k5 = new Car("kia", 2500);
    }

}

class Car{
    String brand;
    int price;

    public Car() { // 매개변수가 없는 생성자

    }

    public Car(String brand, int price) { //매개변수가 있는 생성자
        this.brand = brand;
        this.price = price;
    }
}

 

여기 사용된 'this' 는 참조변수로 인스턴스 자신을 가리킵니다. 인스턴스의 주소가 저장되어 있으며 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재합니다. 위의 코드 처럼 생성자의 매개변수 이름과 인스턴스 변수의 이름이 같을 경우에 인스턴스 변수 앞에 'this' 키워드를 붙여 구분하게 됩니다.

 

 

 

 

모든 클래스에는 반드시 하나의 이상의 생성자가 정의되어 있어야 합니다. 하지만 나는 클래스를 만들 때 생성자를 만들어서 사용한적이 없는데? 라고 생각이 드실 수 있습니다. 생성자를 정의하지도 않고 인스턴스를 생성할 수 있는 이유는 '기본 생성자(default constructor)` 때문입니다.

 

 

 

 

컴파일 할 때 컴파일러가 자동적으로 생성자가 없으면 기본 생성자를 추가하여 컴파일 하게 됩니다.

 

public class ConstructorEx {

    public static void main(String[] args) {
        Car k3 = new Car();
    }

}

class Car{
    String brand;
    int price;
    
    //생성자가 없다!
//    public Car(){ } 자동적으로 기본 생성자 추가!
}

 

 

 

현재 사용하고 있는 인스턴스와 같은 상태를 갖는 인스턴스를 하나 더 만들고자 할 때 생성자를 이용할 수 있습니다.

두 인스턴스가 상태가 같다. 라는 말은 두 인스턴스의 모든 인스턴스 변수가 동일하다는 의미입니다.

this( )를 사용하여 같은 클래스의 다른 생성자를 호출해 복사해보겠습니다. this( ) 메소드는 생성자 내부에서만 사용이 가능합니다.

 

 

public class ConstructorEx {

    public static void main(String[] args) {
        Car k5 = new Car("kia", 2500);
        Car copyK5 = new Car(k5);

        System.out.println(k5.toString());
        System.out.println(copyK5.toString());

        k5.price = 4000; //인스턴스 변수 값 변경
        copyK5.price = 2000; //인스턴스 변수 값 변경

        System.out.println(k5.toString());
        System.out.println(copyK5.toString());
    }

}

class Car{
    String brand;
    int price;

    public Car(String brand, int price) {
        this.brand = brand;
        this.price = price;
    }

    public Car(Car c) { //인스턴스의 복사를 위한 생성자
        this(c.brand, c.price); //다른 생성자 호출!
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + '\'' +
                ", price=" + price +
                '}';
    }
}

출력 결과

 

 

copyK5는 k5를 복사하여 생성하여 같은 상태이지만 독립적인 메모리공간에 존재하는 별도의 인스턴스 입니다. copyK5의 값이 변경되어도 k5에는 영향이 미치지 않습니다.

 

생성자를 잘 활용하면 코드가 간결해지고, 직관적이게 됩니다. 그래서 프로그래머는 좀 더 객체지향적인 코드를 작성할 수 있습니다.