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였습니다.

그렇다면

  1. obj는 Z로 동적 바인딩이 되지 않은 것인지
  2. 그렇다면 어떻게 Y 클래스의 f( )가 호출된
  3. obj.g( )는 왜 X클래스의 값이 나온 것인지
  4. X obj = new Z( );를 어떻게 해석해야 하는지에 대하여 알고 싶습니다.

1 답변

  • 좋아요

    0

    싫어요
    채택 취소하기

    정답은 32가 맞습니다. 위 코드 그대로 실행해보면 "3" + "2"가 출력되네요.

    1. obj는 Z로 동적 바인딩이 되지 않은 것인지
    2. 그렇다면 어떻게 Y 클래스의 f( )가 호출된 (것인지)
    3. obj.g( )는 왜 X클래스의 값이 나온 것인지
    4. X obj = new Z( );를 어떻게 해석해야 하는지에 대하여 알고 싶습니다.

    4번

    X obj = new Z()일 떄 objX로 업캐스팅 Z 클래스의 인스턴스가 할당됐다고 합니다.

    그리고 ZY의 메서드들은 업캐스팅 때문에 '가려진' 상태가 됩니다.

    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번

    동적 바인딩이 어떤걸 의미하는지 잘 모르겠네요. 🤔

    - 끗 -

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)