Skip to main content

[Java] 부모의 생성자와 Override (정보처리기사 25년 1회 실기)


13. 다음은 Java 코드에 대한 문제이다. 아래 코드를 확인하여 알맞는 출력값을 작성하시오.

public class Main {
    public static void main(String[] args) {
        new Child();
        System.out.println(Parent.total);
    }
}
 
 
class Parent {
    static int total = 0;
    int v = 1;
 
    public Parent() {
        total += (++v);
        show();    
    }
 
    public void show() {
        total += total;
    }
}
 
 
class Child extends Parent {
    int v = 10;
 
    public Child() {
        v += 2;
        total += v++;
        show();
    }
 
    @Override
    public void show() {
        total += total * 2;
    }
}
  • 메모리에 Child 객체가 만들어짐 (모든 필드는 기본값으로 초기화됨)
  • super() 호출로 Parent 생성자가 먼저 실행됨
  • 이 시점에서 this는 Child 타입
  • → this.show() 는 Child.show()를 호출하게 됨
  • 그런 다음 Child 생성자가 이어서 실행됨

정답: 54


Parent클래스의 생성자 Parent()에서 show()호출하면 왜 Child 클래스의 show() 가 실행돼?

자식의 인자 없는 생성자를 호출하면 묵시적으로 부모의 인자없는 생성자가 먼저 호출된다. 이 때 부모의 Parent() 생성자에서 show() 메서드를 실행할 때 가까운 부모의 show() 메서드가 실행된다고 오해하기 쉬운데 @Override된 자식의 생성자가 실행된다.

Java에서 생성자 내에서 this.show()를 호출할 때, 실제로 호출되는 메서드는 "현재 객체 타입 기준의 오버라이드된 메서드"이다. main 영역에서 이미 객체는 Child 타입으로 생성되었기 때문에 super() 안에서 호출되는 show()는 Child의 @Override show()가 실행되는 것이다.

이유는 Java의 "가상 메서드 호출(virtual method call)" 원칙 때문이다. Java에서는 모든 인스턴스 메서드 호출은 '실제 객체 타입' 기준으로 동작한다. 즉, Parent 생성자 안에서 this.show()를 호출하면, this는 Child 객체이므로 Child 클래스에서 @Override한 show()가 실행된다는 것이 이 원칙이다.

이건 단순히 시험 문제라서 그렇지 실제 개발에서 생성자에서 오버라이딩된 메서드를 호출하는 건 권장되지 않는다. 그 이유는자식 필드가 아직 초기화되지 않은 상태에서 메서드가 호출될 수 있기 때문이다. 예를 들면 Child의 v는 아직 10으로 초기화되지 않은 상태일 수 있다.