Home > 2024 > Java > ☕️[Java] super - 생성자

☕️[Java] super - 생성자
Java Programming Language

super - 생성자.

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

“상속 관계를 사용하면 자식 클래스의 생성자에서 부모 클래스의 생성자를 반드시 호출해야 합니다.(규칙)”

  • 상속 관계에서 부모의 생성자를 호출할 때는 super(...)를 사용하면 됩니다.

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

ClassA

package extends1.super2;

public class ClassA {
  public ClassA() {
    System.out.println("ClassA 생성자");
  }
}
  • ClaasA는 최상위 부모 클래스입니다.

ClassB

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()를 생략할 수 있습니다.
    • 상속 관계에서 첫줄에 super(...)를 생략하면 자바는 부모의 기본 생성자를 호출하는 super()를 자동으로 만들어 줍니다.
      • 참고로 기본 생성자를 많이 사용하기 때문에 편의상 이런 기능을 제공합니다.

ClassC

package extends1.super2;

public class ClassC extends ClassB {

  public ClassC() {
    super(10, 20);
    System.out.println("ClassC 생성자");
  }
}
  • ClassCClassB를 상속 받았습니다.
  • ClassB는 다음 두 생성자가 있습니다.
    • ClassB(int a)
    • ClassB(int a, int b)
  • 생성자는 하나만 호출할 수 있습니다.
    • 두 생성자 중에 하나를 선택하면 됩니다.
      • super(10, 20)를 통해 부모 클래스의 ClassB(int a, int b) 생성자를 선택했습니다.

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

Super2Main

package extends1.super2;

public class Super2Main {

  public static void main(String[] args) {
    ClassC classC = new ClassC();
  }
}

실행 결과

ClassA 생성자
ClassB 생성자 a=10 b=20
ClassC 생성자
  • 실행해보면 ClassA => ClassB => ClassC 순서로 실행됩니다.
    • 생성자의 실행 순서가 결과적으로 최상위 부모부터 실행되어서 하나씩 아래로 내려오는 것 입니다.
      • 따라서 초기화는 최상위 부모부터 이루어 집니다.
        • 왜냐하면 자식 생성자의 첫 줄에서 부모 생성자를 호출해야 하기 때문입니다.

1~3까지의 과정

  • new ClassC()를 통해 ClassC 인스턴스를 생성합니다.
    • 이때 ClassC()의 생성자가 먼저 호출되는 것이 맞습니다.
      • 하지만 ClassC()의 생성자는 가장 먼저 super(...)를 통해 ClassB(...)의 생성자를 호출합니다.
        • ClassB의 생성자도 부모인 ClassA()의 생성자를 가장 먼저 호출합니다.

4~6까지의 과정

  • ClassA()의 생성자는 최상위 부모입니다.
    • 생성자 코드를 실행하면서 "ClassA 생성자"를 출력합니다.
      • ClassA() 생성자 호출이 끝나면 ClassA()를 호출한 ClassB(...) 생성자로 제어권이 돌아갑니다.
  • ClassB(...) 생성자가 코드를 실행하면서 "ClassB 생성자 a=10 b=20"를 출력합니다.
    • 생성자 호출이 끝나면 ClassB(...)를 호출한 ClassC()의 생성자로 제어권이 돌아갑니다.
  • ClassC()가 마지막으로 생성자 코드를 실행하면서 "ClassC 생성자"를 출력합니다.

정리

  • 상속 관계의 생성자 호출은 결과적으로 부모에서 자식 순서로 실행됩니다.
    • 따라서 부모의 데이터를 먼저 초기화하고 그 다음에 자식의 데이터를 초기화합니다.
  • 상속 관계에서 자식 클래스의 생성자 첫줄에 반드시 super(...)를 호출해야 합니다.
    • 단 기본 생성자(super())인 경우 생략 할 수 있습니다.