객체지향의 가장 큰 장점이라고 한다면 추상화, 상속, 다형성 정도로 추릴수 있는데요. 상속보다는 컴포지션을 사용하자?
아니 왜 멀쩡한 상속을 두고 컴포지션이라는 듣도보도 못한 걸 쓰자는건지 알수가 없지만 좀더 나가보도록 합시다.

일단 상속의 의미부터 짚고 넘어가고 싶은데 보통 상속에 대해서 설명하면 부모로부터 성질을 물려받은 자식이다. 라고 설명을 한다. 솔직히 들어보면 개똥같은 소리다 -_-..

인간의 관점에서 상속이라고 한다면(많이 봐줘서 유전) 자신의 일부를 물려준다. 혹은 닮는다. 같은 의미가 된다.

그러나 내가 풀이하는(전적으로 제 사견입니다..) 상속이란 java 의 예약어인 extends  가 가장 잘 표현한다고 생각한다.
단어 그대로 확장이다. 하나의 기본이 되는 클레스가 있고 그것을 재사용해서 더 큰 개념으로 혹은 구체적인 개념으로 확장해나가는 과정 (추상화>>구체화) 이 상속이라고 이해할수 있을것이다.

약간 두서없는 이야기가 되었지만. 상속에 대해서 좀더 명확히 이해하고 갈필요가 있다는 이야기로 들어주세요.

그런데 컴포지션은 무엇이냐? 
A라는 클레스를 상속(확장)받는 개념이 아니라 A라는 클레스를 사용한다는거다.
이전 항목에서 나왔던 ColorPoint 라는 클레스가 있다면 이것은 Color을 상속받아야 하나 Point를 상속받아야 하나? 상속이 절대적인 방법이다. 라고 한다면 다중상속도 C++이나 다른 객체지향언어에서 사용이 가능하다. 근데 자바는 단일 상속만 되잔아? 안될거야..

이것에 대한 자바의 해결책이 아니라 객체지향 프로그래밍의 좋은 방법중 하나가 컴포지션인것이다.

자바 API 중에서 잘못된 예를 찾아보자.
-뭐라? 자바 API에 잘못된 예가있다니 장난하는거냐? 라고 물을수도 있겠지만 자바도 역사가 그리 짧지는 않다보니 객체지향 프로그래밍의 개념이 지금보다는 명확하지 않았던것이다. 그런 이유로 문제가 있는 클레스가 몇몇 존재한다.

가장 기본적인 자료구조인 Stack 과 Queue 가 대표적이다.
Stack과 Queue에 구현되어야할 메소드는 무엇인가?
집어넣고 꺼내는 단 두가지다.
Stack에는 push, pop 그리고 추가로 peek라는 최상단의 객체를 보기만 하는 기능도 있다.
추가로 size라던가 pushAll 이라던가 하는 부가적인 기능이 있을수도 있다. 
Queue의 경우에는 offer와 poll 두가지만 있으면 된다. 하지만 Stack과 Queue 객체를 생성해보자.
애당초 Queue는 인터페이스인데다가 보통 LinkedList 객체를 생성한다. 거기다가 Queue는 Collection을 상속했다. 

게다가 집어넣는다. 라는 메소드는 offer도 있고 add도 있다. 꺼낸다 라는 메소드는 remove도 있고 poll도 있다.
add와 offer은 API문서를 아무리 읽어봐도 다른점을 못찾겠다 -_-..
remove와 poll 은 꺼낼게 없을경우 remove는 null을 리턴, poll은 예외를 띄워버린다. 

Stack 은 인터페이스 같은거 없다. 그냥 Vector를 상속했다. Vector은 ArrayList 나 LinkedList같은 자료구조다.근데 List를 확정하면 Stack이 되나? ... 

여튼 자바의 흑역사라고 말하는 사람도 있더라..

이제와서 뜯어고치면 하위호환이라는 엄청난 타격을 받기 때문에 어쩔수 없이 냅두는 수밖에 없다.
지금와서 다시 작성한다면 Stack 에는 필요한 몇가지 메소드를 구현하고 LinkedList나 Vector 객체를 컴포넌트로 사용했을것이다. 라고 책은 설명하고 있다. 

요약하자면 확장사용에 대해서 잘 구분하자.
Posted by 동적할당
: