middlefitting

[OOP] 참조변수 super와 생성자 super() 알아보기 본문

JAVA

[OOP] 참조변수 super와 생성자 super() 알아보기

middlefitting 2023. 2. 16. 20:27

this와 this()에 이어 super와 super()에 대해 알아보도록 하겠습니다.

 

이 둘도 완전히 다른 내용인데요, 결론부터 말하면

 

super는 조상의 멤버를 가리키며, 조상의 멤버를 자신의 멤버와 구분하기 위해 사용하고,

 

super()는 조상의 생성자를 호출하는데 사용합니다.

 

 

 

참조변수 super

public class Chair {
    String color;
    int weight = 20;
}

class ChairChild extends Chair{
    int weight = 10;
    
    void info() {
        System.out.println(super.weight);
        System.out.println(weight);
    }

    public static void main(String[] args) {
        ChairChild chairChild = new ChairChild();
        chairChild.info();
        // 20
        // 10
    }
}

예를 들어 위와 같은 코드를 호출하면 결과는

20

10

이 나오게 됩니다.

 

왜냐면 자식 클래스에서 weight가 10으로 초기화 되었지만 부모 클래스에서는 20으로 초기화 되었기 때문입니다.

 

따라서 참조변수 super를 통한 부모의 인스턴스 변수와, 본인의 인스턴스 변수는 다른 결과를 가지게 되는 것입니다.

 

 

 

생성자 super()

 

생성자 super()는 부모의 생성자를 호출하는 것을 말합니다.

 

이것 또한 코드 구성에 따라 적절하게 활용할 수 있을 것입니다.

 

그리고 super() 실제로 정말 많은 코드에서 사용되고 있으며 사용되어야 합니다.

 

정말 재미있는 규칙인데 사실 위의 코드는 실제로는 다음과 같이 구성되어 있습니다.

public class Chair {

    public Chair() {
        super();
    }

    String color;
    int weight = 20;
}

class ChairChild extends Chair{
    int weight = 10;
    
    public ChairChild() {
        super();
    }    
    
    void info() {
        System.out.println(super.weight);
        System.out.println(weight);
    }

    public static void main(String[] args) {
        ChairChild chairChild = new ChairChild();
        chairChild.info();
    }
}

모든 클래스는 생성자를 가져야 하기 때문에 아무런 생성자를 정의하지 않았다면, 디폴트 생성자를 가지게 됩니다.

 

그리고 생성자에는 다음과 같은 규칙이 존재합니다.

 

"모든 생성자는 생성자를 호출하여야 한다."

 

해당 디폴트 생성자에서는 아무런 this()나 별도의 super()를 호출하지 않았으므로 모두 super()를 호출하는 것입니다.

 

ChairChild에서는 자신의 부모인 Chair의 생성자를 호출할 텐데, Chair는 누구의 생성자를 호출하는 것일까요.

 

그것은 바로 모든 클래스의 조상님이라는 Object 클래스입니다.

 

즉 Chair에서 super()은 Object의 생성자를 호출하게 되는 것이고 이러한 규칙 덕분에

 

모든 객체에서 toString equals 등의 메서드들을 마치 당연하듯이 사용할 수 있는 것입니다.