상속_메모리 구조
김영한 님께서 말씀하시길.
정말정말 정말 중요한 내용이니 꼭 이해 하랍신다.
SubBird bird = new SubBird();
new SubBird()를 호출하면 어떤 일이 벌어질까?
SubBird 의 인스턴스가 생성된다.
public class SubBird extends SuperAnimal{
public void fly() {
System.out.println("새는 하늘을 날지.");
}
}
여기서 SubBird 는 SuperAnimal 클래스를 상속한다. SuperAnimal 클래스의 코드를 재'사용' 한다는 뜻이다.
SuperAnimal 클래스를 사용!
코드를 사용하려면 뭐다? 인스턴스를 생성해야 한다.
결론 - 상속 관계를 갖는 하위 클래스의 인스턴스를 생성하면, 해당 클래스의 상위 클래스의 인스턴스까지 생성된다.
상속의 목적이 코드의 재사용이며, 코드를 사용하기 위해선 클래스의 인스턴스를 생성해야 하기 때문이다.

SubBird 인스턴스 생성 ->
어? Subird가 SuperAnimal 을 상속하네? 사용한다는 소리지? SuperAnimal 인스턴스 생성
-> 같은 그룹이라고 봐도 무방하니 관리상의 편의를 위해 하나의 주소값에 몰아넣기~
-> 참조변수에 주소값 할당. 해당 주소값은 super , sub인스턴스가 함께 담겨 있는 메모리 주소임.
자 이렇게, 1개의 주소값에 상위, 하위 클래스가 공존하게 되었다.
이러한 메모리 메모리 구조를 바탕으로, 하위 클래스에서 상위 클래스의 정보에 쉽게 접근할 수 있게 된다.
eat() 은 SubBird 인스턴스에 없으므로 동일 주소값에 있는 SuperAnimal 인스턴스의 정보를 읽어 사용할 수 있게 한다.
..멋져..
섹시하다.

여기서 하나 짚고 갈 부분이 있다.
SubBird bird = new SubBird(); 에서 SubBird는 SuperAnimal 을 상속받으므로, 하나의 주소값에 SubBird, SuperAnimal 인스턴스가 생성된다고 했다.
즉. 주소값.eat() 만으로는 SuperAnimal 에 접근해야 하는지, SubBird 에 접근해야 하는지 선택할 수 없다.
이러한 선택의 모호점을 타파하기 위해 한 가지 기준이 존재하는데, 바로 호출되는 참조변수의 타입이다.
SubBird bird = new SubBird(); 이므로
참조변수에는 SubBird 의 인스턴스가 기준이다.
따라서 bird.eat() 으로 함수를 호출하게 되면
1. SubBird 인스턴스를 참조. eat() 조회.
2. 없다면 SubBird 의 상위 클래스인 SuperAnimal 을 참조. eat() 조회.
3. eat() 가 발견되면 해당 메서드 return 된다.
요약
1. 상속관계에 있는 클래스를 생성하면, 상속 받고 있는 클래스의 인스턴스도 같이 생성된다. 이 때, 인스턴스들은 같은 메모리 주소값에 할당된다.
2. 접근 경로를 지정해야 하는데 같은 주소값에 여러 인스턴스가 존재하므로, 접근 경로의 기준은 호출하는 변수의 타입(클래스)를 기준으로 한다.
3. 2에서 찾는 내용이 없다면 상위 인스턴스를 조회하게 된다. 끝까지 거슬러 올라가도 찾는 내용이 없으면 컴파일 에러.