Java 예제 풀이 질문
조회수 428회
class X {
public void f( ) { System.out.print("1"); }
public static void g() { System.out.print("2"); }
}
class Y extends X{
public void f( ) { System.out.print("3"); }
}
class Z extends Y {
public static void g( ) { System.out.print("4"); }
}
public class num23 {
public static void main(String args[]) {
X obj = new Z( );
obj.f( );
obj.g( );
}
}
obj.f ( ): Z클래스에서의 f( ) 호출, 부모클래스의 f( )호출하여 3 출력
obj.g( ): Z클래스의 g( ) 호출하여 4출력
출력 결과: 34
위와 같은 형식으로 풀었는데 정답은 32였습니다.
그렇다면
- obj는 Z로 동적 바인딩이 되지 않은 것인지
- 그렇다면 어떻게 Y 클래스의 f( )가 호출된
- obj.g( )는 왜 X클래스의 값이 나온 것인지
- X obj = new Z( );를 어떻게 해석해야 하는지에 대하여 알고 싶습니다.
1 답변
-
정답은 32가 맞습니다. 위 코드 그대로 실행해보면 "3" + "2"가 출력되네요.
- obj는 Z로 동적 바인딩이 되지 않은 것인지
- 그렇다면 어떻게 Y 클래스의 f( )가 호출된 (것인지)
- obj.g( )는 왜 X클래스의 값이 나온 것인지
- X obj = new Z( );를 어떻게 해석해야 하는지에 대하여 알고 싶습니다.
4번
X obj = new Z()
일 떄obj
는X
로 업캐스팅Z
클래스의 인스턴스가 할당됐다고 합니다.그리고
Z
와Y
의 메서드들은 업캐스팅 때문에 '가려진' 상태가 됩니다.2번
Y.f()
는 가려진 상태이기 때문에 호출이 안될거라고 생각할 수 있습니다. 하지만 이 상속관계에서X.f()
는 (호출이 가능하도록)Y.f()
로 인도하는 역할만 수행한다고 생각하면 됩니다. 실제로 호출되는 것은X.f()
를 오버라이딩한Y.f()
입니다. (왜 때문에 이렇게 되는지를 물으신다면... 자바가 그냥 원래 그렇습니다 🤭)그래서 실제로 출력되는 값은
"3"
이 맞고, 코드를 정석대로 고치면 이렇게 됩니다:class Y extends X { @Override // 이 어노테이션은 기능적인 요소는 없고 그냥 코멘트와 비슷한 역할을 합니다. public void f( ) { System.out.print("3"); } }
예를 들어서 이런 클래스가 있다고 했을 때:
public class Wahappen { @Override public String toString() { return "Wa happening here"; } }
다음처럼 모든 클래스의 슈퍼 클래스인
Object
로 업캐스팅을 해보죠:Object obj2 = new Wahappen(); System.out.println(obj2.toString()); // "Wa happening here"
여기서
obj2.toString()
은Object.toString()
을 가리키지만 실제로 실행되는 것은Wahappen.toString()
입니다.3번
스태틱 메서드는 상속에서 제외됩니다. 그리고
X.g()
는 스태틱 메서드이기 때문에 스태틱으로 호출해야 합니다. 따라서 아래처럼 인스턴스를 통한 호출은 잘못된 방법입니다:X obj = new Z( ); obj.g();
하지만 Java가 보정해주기 때문에 딱히 에러는 발생하지 않는데요. 자동으로 아래처럼 바뀌기 때문입니다:
X obj = new Z( ); //obj.g(); X.g();
아래 다른 예시를 첨부합니다:
public class StaticMethodsHeritance { public static void main(String[] args) { Parent instance = new Child(); instance.print(); // Child 출력됨 instance.staticPrint(); // Parent 출력됨 } } class Parent { public void print() { System.out.println("Parent"); } public static void staticPrint() { System.out.println("Parent"); } } class Child extends Parent { public void print() { System.out.println("Child"); } public static void staticPrint() { System.out.println("Child"); } }
1번
동적 바인딩이 어떤걸 의미하는지 잘 모르겠네요. 🤔
- 끗 -
댓글 입력