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);
}
}
-
ClassB
는ClassA
를 상속 받았습니다.- 상속을 받으면 생성자의 첫 줄에
super(...)
를 사용해서 부모 클래스의 생성자를 호출해야 합니다.- 예외로 생성자 첫줄에
this(...)
를 사용할 수는 있습니다.- 하지만
super(...)
는 자식의 생성자 안에서 언젠가는 반드시 호출해야 합니다.
- 하지만
- 예외로 생성자 첫줄에
- 상속을 받으면 생성자의 첫 줄에
- 부모 클래스의 생성자가 기본 생성자(파라미터가 없는 생성자)인 경우에는
super()
를 생략할 수 있습니다.- 상속 관계에서 첫줄에
super(...)
를 생략하면 자바는 부모의 기본 생성자를 호출하는super()
를 자동으로 만들어 줍니다.- 참고로 기본 생성자를 많이 사용하기 때문에 편의상 이런 기능을 제공합니다.
- 상속 관계에서 첫줄에
ClassC
package extends1.super2;
public class ClassC extends ClassB {
public ClassC() {
super(10, 20);
System.out.println("ClassC 생성자");
}
}
-
ClassC
는ClassB
를 상속 받았습니다. -
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()
)인 경우 생략 할 수 있습니다.
- 단 기본 생성자(