회원가입

상속 - super

Beany 2024-10-06

ChatGPT 요약

부모 클래스의 필드나 메서드와 자식 클래스의 필드나 메서드가 같을 때, 자식 클래스에서 부모 클래스의 것을 사용하려면 "super" 키워드를 사용한다. 또한, 상속 관계에서 자식 클래스의 생성자에서 부모 클래스의 생성자를 호출할 때도 "super" 키워드를 사용하여 호출해야 한다. "super"를 이용하여 부모 클래스의 생성자를 호출하는 방법과 주의할 점을 살펴보았다.

super - 부모 참조


부모와 자식의 필드명이 같거나 메서드가 오버라이딩 되어 있으면, 자식에서 부모의 필드나 메서드를 호출할 수 없다. 이때 super 키워드를 사용하면 부모를 참조할 수 있다. super 는 이름 그대로 부모 클래스에 대한 참조를 나타낸다.

다음 예를 보자. 부모의 필드명과 자식의 필드명이 둘다 value로 똑같다. 메서드도 hello()로 자식에서 오버라이딩 되어 있다. 이때 자식 클래스에서 부모 클래스의 valuehello() 를 호출하고 싶다면 super 키워드를 사용하면 된다.

package extends1.super1;

public class Parent {
    public String value = "parent";

    public void hello() {
        System.out.println("Parent hello()");
    }
}
package extends1.super1;

public class Child extends Parent{
    public String value = "child";

    @Override
    public void hello() {
        System.out.println("Child hello()");
    }

    public void call() {
        System.out.println("this.value: " + this.value);
        System.out.println("super.value: " + super.value);

        this.hello();
        super.hello();
    }
}
package extends1.super1;

public class Super1Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.call();
    }
}
this.value: child
super.value: parent
Child hello()
Parent hello()

 

 

super - 생성자


상속 관계의 인스턴스를 생성하면 결국 메모리 내부에는 자식과 부모 클래스가 각각 다 만들어진다. Child 를 만들면 부모인 Parent 까지 함께 만들어지는 것이다. 따라서 각각의 생성자도 모두 호출되어야 한다.

상속 관계를 사용하면 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출해야 한다. (규칙)
상속 관계에서 부모의 생성자를 호출할 때는 super(...)를 사용하면 된다.

예제를 통해 상속 관계에서 생성자를 어떻게 사용하는지 알아보자.

package extends1.super2;

public class ClassA {
    public ClassA() {
        System.out.println("ClassA 생성자");
    }
}
package extends1.super2;

public class ClassB extends ClassA {
    public ClassB(int a) {
        super();  // 기본 생성자 생략 가능
        System.out.println("ClassB 생성자 a=" + a);
    }

    public ClassB(int a, int b) {
        super();  // 기본 생성자 생략 가능
        System.out.println("ClassB 생성자 a=" + a + ", b=" + b);
    }
}

ClassBClassA 를 상속 받았다. 상속을 받으면 생성자의 첫줄에 super(...) 를 사용해서 부모 클래스의 생성자를 호출해야 한다.

  • 예외로 생성자 첫줄에 this(...)를 사용할 수는 있다. 하지면 super(...)는 자식의 생성자 안에서 언젠가는 반드시 호출해야 한다. 
  • 부모 클래스의 생성자가 기본 생성자(파라미터가 없는 생성자)인 경우에는 super() 를 생략할 수 있다.
package extends1.super2;

public class ClassC extends ClassB {
    public ClassC() {
        // ClassB 에서 생성자를 정의
        // 생성자를 직접 정의한 경우 ClassB에서 ClassB() 는 자동으로 생성되지 않음
        // 그래서 super() 를 호출할 수 없음, 컴파일 에러
        super(10, 20);
        System.out.println("ClassC 생성자");
    }
}
package extends1.super2;

public class Super2Main {
    public static void main(String[] args) {
        ClassC c = new ClassC();
    }
}
ClassA 생성자
ClassB 생성자 a=10, b=20
ClassC 생성자

ClassC ClassB 를 상속 받았다. ClassB 다음 두 생성자가 있다.

  • ClassB(int a)
  • ClassB(int a, int b)

생성자는 하나만 호출할 수 있다. 두 생성자 중에 하나를 선택하면 된다.

참고로 ClassC 의 부모인 ClassB 에는 기본 생성자가 없다. 따라서 부모의 기본 생성자를 호출하는 super() 를 사용하거나 생략할 수 없다.

 

0 0
JAVA
이 공간은 개인 공부를 통해 얻은 정보를 체계적으로 정리하고 공유하는 곳입니다. 학습한 내용, 발견한 지식, 그리고 문제 해결 방법 등을 기록하여 나만의 학습 자료를 구축하고, 필요할 때 쉽게 참고할 수 있는 유용한 자원으로 활용할 수 있도록 합니다.
Yesterday: 456
Today: 192