상속 관계의 객체를 생성하면 그 내부에는 부모와 자식이 모두 생성된다.
public class Child extends Parent
자식 클래스인 Child가 부모 클래스 Parent를 상속받은 경우를 생각해보자.
상속받는다고 해서 부모와 자식이 합쳐진 하나가 생성될 것 같지만(=내 생각), 그렇지 않다.
단순히 부모의 필드와 메서드만 물려 받는게 아니다. 상속 관계를 사용하면 부모 클래스도 함께 포함해서 생성된다. 외부에서 볼때는 하나의 인스턴스를 생성하는 것 같지만 내부에서는 부모와 자식이 모두 생성되고 공간도 구분된다.
new Child()를 호출하면 Child뿐만 아니라 상속 관계에 있는 Parent까지 함께 포함해서 인스턴스를 생성한다. 참조값은 x001 로 하나이지만 실제로 그 안에서는 Parent, Child 라는 두가지 클래스 정보가 공존하는 것이다.
💡 내부에 부모와 자식이 모두 존재한다면, child.test()를 호출했을때 부모와 자식 중 어디에서 찾을 것인가?
▶ 호출하는 변수의 타입(클래스)을 기준으로 선택한다.
Parent parent = new Child();
Child child = new Child();
parent.test(); //부모에서 test()호출
child.test(); //자식에서 상속받은 test()호출
출력값이 같더라도, 어느 것을 호출했느냐는 다르다는 것이다.
위의 예제에서 child는 자식타입이 기준이니 자식에 먼저 가서 Test()를 찾고, 자식에 없으면 상속관계인 부모에게 가서 Test()를 찾을 것이다.
만약 부모에서도 해당 기능을 찾지 못하면 더 상위 부모에서 필요한 기능을 찾아본다. 부모에 부모로 계속 올라가면서 필드나 메서드를 찾는 것이다(자식 → 부모 일방통행).
물론 계속 찾아도 없으면 컴파일 오류가 발생한다.
'먼저' 어디서 찾냐가 중요한 이유는 사용할 수 있는 메서드에 차이가 있기 때문이다.
Parent parent = new Child();
이 경우, Child에는 있고 Parent에는 없는 메서드들은 사용할 수 없다.
내용을 정리하면 상속의 중요한 두 가지 개념은 다음과 같다.
1. 메서드 호출 시 호출하는 변수의 타입(클래스)을 기준으로 호출
2. 메서드 상속은 일방통행 (자식 → 부모)
위의 메모리 구조는 '다형성'을 이해하는데도 큰 도움이 된다.