상속은 상위 클래스기능을 하위 클래스로 확장하고 재사용하는 기술

상속은 상위 클래스기능을 하위 클래스로 확장하고 재사용하는 기술

 

상속 : 재사용 + 확장

 

상속은 조직도가 아니라 재사용과 확장으로 이해하는 것이 맞다. 즉, 분류도로 이해해야 한다.

 

동물은 포유류의 부모가 아니다. 고래의 부모가 포유류일 수도 없다.

동물 중 분류를 조금더 세분화해서 포유류와 조류가 나온다.

포유류를 조금 더 분류해서 고래, 박쥐가 나오는 것이다.

 

객체 지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가 확장해서 사용할 수 있다는 의미이다.

 

정리

-객체지향의 상속은 상위 클래스의 특성을 재사용하는 것이다.

-객체지향의 상속은 상위 클래스의 특성을 확장하는 것이다.

-객체지향의 상속은 is a kind of 관계를 만족해야 한다.

(해석:하위 클래스는 상위 클래스의 한 분류다.)

(예제:고래는 동물의 한 분류다)

 

상위 클래스 (상위분류) - 하위 클래스(하위분류) 라고 생각을 하자.

상위 클래스 쪽으로 갈 수록 추상화, 일반화 됐다고 말하며, 하위 클래스 쪽으로 갈수록 구체화, 특수화 되었다고 이야기 한다.

 

 

 

다시 말해서 객체지향의 상속은 부모 - 자식 같은 계층도가 아니라 동물 - 포유류 같은 분류도라는 사실을 기억하자.

 

상속관계에서 반드시 만족해야 할 문장이 있다.

 

하위 클래스는 상위 클래스다.! (리스코프 치환원칙)

 

아버지는 할아버지다???(조직도인경우)

아들은 아버지다???(조직도인경우)

 

포유류는 동물이다. (분류도인경우)

고래는 포유류이다.(분류도인경우)

 

아버지 영희아빠 = new 딸();

// 딸을 낳으니 아버지 역할을 하는 영희아빠라 이름지었다???? (x)

 

 

동물 뽀로로 = new 펭귄();

//펭귄을 낳으니 동물 역할을 하는 뽀로로라 이름 지었다. (o)

 

 

상속의 강력함

 

상위 클래스에서만 showMe() 메서드를 구현했지만 모든 하위 클래스의 객체에서 showMe() 메서드를 사용할 수 있다.

 

상속한다는 것이 이렇게 상위 클래스의 특성을 상속한다는 의미이지 부모-자식 관계는 아니다.

 

하위 클래스에서 showMe() 메서드를 다시 작성하지 않아도 된다는것, 재사용할 수 있다는 것은 정말 획기적인 일이다.

 

하위 클래스는 상위 클래스다.

즉, 하위 분류는 상위 분류이다. 라는 말이 코드에서 어떻게 표현되는지 알 수 있다.

포유류 한마리는 동물이 맞다. 고래 한마리는 동물이 맞다.

이처럼 객체 지향은 현실 세계를, 인간의 논리를 그대로 코드로 옮길 수 있는 힘이 있다.

 

 

위 코드 처럼 반복문 하나면 모든 동물들이 자신을 드러낼 수 있다.

이건 흡사 초등학교에서 남자학생 모이세요, 여자 모이세요 라고 외치는 효과를 불러 온다.

(반응하는 객체의 수가 달라진다.)

 

또한 클래스 상속 구조에서 최상위 클래스는 Object다. 그래서 모든 클래스는 결국 Object의 특성을 물려받는다.

그래서 어떤 클래스의 인스턴스이든 상관없이 개발자는 toString() 메서드를 사용할 수 있는 것이다.

 

정리

객체지향의 상속은 하위 클래스의 특성을 재사용하는 것이다.

객체지향의 상속은 상위 클래스의 특성을 확장하는 것이다.

객체지향의 상속은 is a kind of 관계를 만족해야 한다.

 

상속과 인터페이스

인터페이스는 상속과는 다르게 쓰이는것이 유용하다.

 

인터페이스 : 구현 클래스 is able to 인터페이스

해석: 구현 클래스는 인터페이스 할 수 있다.

예제: 고래는 헤엄칠 수 있다.

 

 

 

상위 클래스는 하위 클래스에게 물려줄 특성이 많을 수록 좋을까? 적을 수록 좋을까?

인터페이스는 구현을 강제할 메서드가 많을 수록 좋을까? 적을 수록 좋을까?

 

답은 상위 클래스는 물려줄 특성이 풍성할 수록 좋고(리스코프 치환원칙), 인터페이스는 구현을 강제할 메서드의 개수가 적을 수록 좋다.(인터페이스 분할 원칙)

 

 

상속과 메모리

동물 클래스가 있고, 펭귄 클래스가 있다.

 

펭귄 클래스가 동물 클래스를 상속하고 있다.

 

펭귄 클래스의 인스턴스만 힙 영역에 생긴게 아니라 Animal 클래스의 인스턴스도 함께 힙 영역에 생긴 것을 볼 수 있다.

 

하위 클래스가 생성될 때 상위 클래스의 인스턴스도 함께 생성된다.

실제로는 Animal 인스턴스 외에도 하나의 객체가 더 생성된다.

(모든 클래스의 최상위 클래스인 Object 클래스의 인스턴스도 함께 생성 되는 것이다.)

13번째 줄을 실행한 후 메모리 변화

 

pingu 객체 참조 변수가 가리키고 있는 것은 Penguin 인스턴스가 아닌 Animal 인스턴스다.

 

pingu 객체 참조 변수는 사실 펭귄이면서 자신이 펭귄이라는 사실을 모르고 있다.

 

다만 자신이 동물이라는 것만 인식하고 있다.

 

따라서 pingu 객체 참조 변수는 16번째 줄에 나타난 펭귄의 서식지 속성과 19번째 줄의 showHabitat() 메서드를 사용할 수 없다.

 

(새로운 객체를 만들어서 상위 클래스로 받으면 하위 클래스의 속성과 메서드를 사용할 수 없다.)

참고로 형변환을 이용할 수 있다

 

클래스명은 클래스 답게 분류로, 객체 참조 변수명은 객체명 답게