인프런 커뮤니티 질문&답변

Rim님의 프로필 이미지
Rim

작성한 질문수

김영한의 실전 자바 - 기본편

다형성과 메서드 오버라이딩

다형적 참조의 오버라이딩

작성

·

436

·

수정됨

0

 학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.
1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
다른 분께서 올려주신 질문 글을 읽고 저 또한 같은 의문이 생겼지만, 그에 대한 답변이 저에게는 잘 와 닿지 않아서 제가 이해한 바를 적어봅니다. 

 

상속 관계에 있는 객체의 메서드를 사용할 때는, 우선 메서드를 사용하는 변수의 참조값을 따라 인스턴스를 찾고, 인스턴스 내의 변수 타입과 동일한 클래스 타입부터 시작하여 메서드를 찾는다고 하셨습니다. 그리고 이렇게 메서드를 찾을 때는 자식 클래스에서 부모 클래스 방향으로 올라가는 것만 가능하고, 부모 클래스에서는 자식 클래스에 대한 정보가 없으므로 반대는 불가능하다고 말씀하셨습니다. 

 

그런데 부모 변수가 자식 인스턴스를 참조하는 다형적 참조의 경우, 메서드를 호출하는 변수의 타입은 부모 클래스이므로 메서드를 부모 클래스에서 찾을 것이고, 부모 클래스는 자식 클래스에 대한 정보가 없는데 어떻게 자식 클래스에 해당 메서드가 오버라이딩이 되었는지 판단하는지 잘 이해가 되지 않았습니다. 

 

제 식대로 내린 결론은 다음과 같습니다.

다형적 참조에서는 변수의 타입은 Parent지만, 이 변수가 참조하는 것은 자식 인스턴스인 Child입니다. 호출된 메서드를 찾을 때는 변수의 타입과 같은 Parent에서 탐색하는 것은 맞지만, 오버라이딩 여부는 Child 인스턴스 내에서 별개로 확인하는 것이고 Parent 인스턴스와는 무관합니다.제가 이해한 방식이 맞나요?

답변 2

2

안녕하세요!

 

해당 부분에서 저도 비슷한 의문이 있어서 알아본 결과를 공유드립니다!

 

먼저,

  • 매서드를 사용하는 변수의 참조값을 따라 인스턴스를 찾고 (Child)

  • 인스턴스 내의 변수 타입과 동일한 클래스 타입부터 시작하여(Parent?) 메서드를 찾는다

이 부분에서 "변수 타입과 동일한 클래스 타입" 을 Parent 라고 생각 할 수 있지만, 사실 그렇지 않습니다.

 

한 번 간단한 테스트를 돌려봤는데요!

 

    @Test
    void foo_instance_info_wildcard(){
        Parent foo = new Child();

        Class<?> aClass = foo.getClass(); // 인스턴스의 클래스 정보

        String simpleName = aClass.getSimpleName(); // 해당 클래스의 이름(패키지 미포함)
        
        System.out.println(simpleName);

        assertEquals("Child", simpleName);
    }

 

해당 테스트는 통과하며, 출력 결과는 Child 로 나옵니다.

 

이 부분에서 실제 런타임에서 동작하는 타입과 (우리가 getSimpleName() 으로 가져온 타입) 컴파일 시점의 타입이(명시된 Parent타입) 다르다는 것을 확인 가능합니다.

 

그리고 이 부분에 대한 글이 있어, 공유드립니당

[Compile-Time Type VS Run-Time Type]

 

결과적으로 "변수의 타입과 같은 Parent에서 탐색하는 것" 이 아닌, 인스턴스가 가진 타입 정보인 Child부터 시작하여 Parent 측으로 올라가는 식으로 매서드를 찾게 됩니다.

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. Rim님

Kim DongKyun님이 잘 이야기를 해주셨는데요.

컴파일 타임에는 인스턴스의 정보를 알 수 없지만, 런타임에는 인스턴스의 정보를 알 수 있습니다.

메서드 오버라이딩은 런타임에 작동하기 때문에 런타임의 인스턴스 정보를 통해서 작동합니다.

감사합니다.

Rim님의 프로필 이미지
Rim
질문자

답변 감사드립니다. Kim DongKyun님과 김영한님의 답변을 통해 처음 의문은 해소된 것 같습니다. 그런데 두 분의 답변에 따르면, 메서드 오버라이딩이 작동하는 런타임에는 "변수 타입과 동일한 클래스 타입"이 Child이므로 Child에서부터 메서드를 탐색하는 것으로 이해되는데, 그렇다면 영상 및 수업자료에서 말씀해주신 내용과는 다른 것으로 생각됩니다. 런타임에 대해 자세히 몰라도 이해할 수 있도록 설명해주신건가요? 해당 부분을 사진으로 첨부하였으나 혹시 문제가 된다면 삭제하겠습니다.

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. Rim님

여기서 poly가 참조하는 것은 Child 인스턴스가 맞습니다.

그런데 Child 인스턴스는 상속을 받았기 때문에 내부에 Child와 Parent가 모두 존재합니다.

이때 어디서부터 탐색을 시작할지는 호출할 때 지정합니다. 여기서 poly 변수가 Parent 타입이기 때문에 Child 인스턴스에 있는 Parent 부분부터 시작하게 됩니다.

감사합니다.

Rim님의 프로필 이미지
Rim
질문자

답변 감사합니다. 그런데 그래도 이해가 되지 않아 죄송하지만 마지막으로 여쭤보겠습니다.

아래 DongKyun님께서

결과적으로 "변수의 타입과 같은 Parent에서 탐색하는 것" 이 아닌, 인스턴스가 가진 타입 정보인 Child부터 시작하여 Parent 측으로 올라가는 식으로 매서드를 찾게 됩니다.

라고 마무리하셨는데, 영한님께서 지금 말씀하신 내용과 반대되는 것 같습니다. 이 부분은 잘못된 것으로 이해하고 넘어가면 될까요?

김영한님의 프로필 이미지
김영한
지식공유자

네 이 부분은 제가 말씀드린 내용으로 이해하시면 됩니다 🙂

Rim님의 프로필 이미지
Rim
질문자

네 감사합니다!

Rim님의 프로필 이미지
Rim

작성한 질문수

질문하기