Skip to main content

[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의 생성자가 실행됨.
  • 하지만 그 전에 자바는 항상 부모 생성자부터 차례로 호출한다.

순서별 호출 흐름

  1. new C(1000) 실행 → C 생성자 호출
  2. C 생성자에서 super(a / 10)super(1000 / 10)super(100) → B 생성자 호출
  3. 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)**의 객체를 대입하는 것이다.


왜 이렇게 쓰는가?

  • CB를 상속하고, BA를 상속하므로 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 타입엔 없음)
    }
}