[Java] 상속: 생성자 호출 순서
생성자의 묵시적 호출, 매개변수 문제
class A {
A() {
System.out.printf("%d", 10); // sys → System, printf → OK
}
}
class B extends A {
B(int a) {
System.out.printf("%d", a); // Sys → System
}
}
class C extends B {
C(int a) {
super(a / 10); // B의 생성자 호출
System.out.printf("%d", a); // sys → System
}
}
public class Test {
public static void main(String[] args) {
A b = new C(1000);
}
}
A b = new C(1000);
- 업캐스팅 (Upcasting)으로 부모 타입(A)의 변수 b에 자식 클래스(C)의 객체를 대입하는 것이다.
new C(1000)
을 호출하면 C의 생성자가 실행됨.- 하지만 그 전에 자바는 항상 부모 생성자부터 차례로 호출한다.
순서별 호출 흐름
new C(1000)
실행 → C 생성자 호출- C 생성자에서
super(a / 10)
→super(1000 / 10)
→super(100)
→ B 생성자 호출 - B 생성자는 또
super()
가 생략되어 있음 → A 생성자 호출
실제 호출 순서
A()
→ 출력:10
B(100)
→ 출력:100
C(1000)
→ 출력:1000
최종 출력 결과
101001000
각 숫자는 System.out.printf("%d", ...)
에 의해 줄바꿈 없이 출력되기 때문에 이렇게 나온다.
A b = new C(1000); 관련
업캐스팅 (Upcasting)
A b = new C(1000);
이 구문은 부모 타입(A)의 변수 b
에 **자식 클래스(C)**의 객체를 대입하는 것이다.
왜 이렇게 쓰는가?
C
는B
를 상속하고,B
는A
를 상속하므로C
는 결국A
의 자식- 그래서
A
타입으로도C
객체를 참조할 수 있다.
A b = new C(1000); // ✅ 업캐스팅
- 업캐스팅은 항상 자동으로 허용된다.
- 다만 이렇게 참조하면
b
로는A
클래스의 멤버(메서드, 필드)만 접근 가능하고,C
에만 있는 것들은 직접 사용할 수 없다.
예시
class A {
void greet() { System.out.println("Hello from A"); }
}
class C extends A {
void sayBye() { System.out.println("Bye from C"); }
}
public class Main {
public static void main(String[] args) {
A obj = new C(); // 업캐스팅
obj.greet(); // ✅ 가능
// obj.sayBye(); // ❌ 컴파일 에러 (A 타입엔 없음)
}
}