본문 바로가기

Java/Java

(JAVA) 디폴트 생성자(default constructor)

class Parent {
    private int money;
    private String name;

    public Parent(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Child extends Parent{

    public Child(int money, String name) {

    }
}

다음 코드는 정상적인 코드인가?

 

answer) 다음 코드를 실행하면 컴파일 오류가 발생한다.

 

 

이유는 무엇일까?

부모 클래스에 디폴트생성자가 선언되어있지 않기 때문

 

디폴트생성자는 선언 안해줘도 컴파일 시 자동으로 생성해준다고 하지않나?

그건 오버로딩을 하지 않았을 때의 말이다.

특정 파라미터를 포함하는 생성자를 오버로딩하였을때 디폴트 생성자는 자동으로 생성되어지지 않는다.

 

위의 코드에서 부모 클래스에서 디폴트 생성자가 선언되어야하는 이유는?

자식 객체가 생성이 되면 자식 객체만 선언되는 것이 아니라 상위 클래스인 부모의 객체와 오브젝트 클래스도 생성이 된다.

(Constructor chaining)

 

*이때 부모에 해당하는 디폴트 생성자가 자동으로 생성되어지지 않았기 때문에 힙 메모리에 부모의 객체가 올라가지 않아 컴파일 오류가 발생한다.

 

 

개선된 코드

 

1. 부모 클래스에 디폴트 생성자 생성

class Parent {
    private int money;
    private String name;

    protected Parent() {
        
    }
    
    public Parent(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Child extends Parent{

    public Child(int money, String name) {

    }
}

 

2. 자식 클래스에 super 메서드 추가

class Parent {
    private int money;
    private String name;


    public Parent(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Child extends Parent{

    public Child(int money, String name) {
        super(money, name);
    }
}

그러면 자바는 왜 굳이 생성자 오버라이딩시 디폴트생성자의 자동생성을 막았는가?

 

제약을 주기 위해서 이다.

 

즉, 부모클래스에서 디폴트 생성자를 선언하지 않고 특정 파라미터를 포함하는 생성자를 오버라이딩 했다고 생각하자.

이것의 의미는 자식클래스에서 부모클래스의 생성자를 무조건 호출하도록 강제하는 것과 같다. (like overring)