본문 바로가기

공부 기록/Java

[이펙티브 자바 3/E] 아이템18 - 상속보다는 컴포지션을 사용하라

- 이 장에서의 '상속'은 인터페이스 상속이 아닌 클래스가 다른 클래스를 확장하는 구현 상속을 말한다.


- 메서드 호출과 달리 상속은 캡슐화를 깨뜨린다.

- 구현 상속의 문제를 모두 피해 가는 묘안이 있다. 기존 클래스를 확장하는 대신, 새로운 클래스를 만들고 private 필드로 기존 클래스의 인스턴스를 참조하게 하자. 기존 클래스가 새로운 클래스의 구성요소로 쓰인다는 뜻에서 이러한 설계를 컴포지션(composition; 구성)이라 한다.

- 새 클래스의 인스턴스 메서드들은 (private 필드로 참조하는) 기존 클래스의 대응하는 메서드를 호출해 그 결과를 반환한다. 이 방식을 전달이라 하며, 새 클래스의 메서드들을 전달 메서드라 부른다.

=> 새로운 클래스는 기존 클래스의 내부 구현 방식의 영향에서 벗어나며, 심지어 기존 클래스에 새로운 메서드가 추가되더라도 전혀 영향받지 않는다.

- 컴포지션과 전달의 조합은 넓은 의미로 위임이라고 부른다.


- 상속은 반드시 하위 클래스가 상위 클래스의 '진짜' 하위 타입인 상황에서만 쓰여야 한다. => is-a 관계일 때만 상속해야 한다.

- 컴포지션을 써야 할 상황에서 상속을 사용하는 건 내부 구현을 불필요하게 노출하는 꼴이다.


[핵심 정리]

상속의 취약점을 피하려면 상속 대신 컴포지션과 전달을 사용하자. 특히 래퍼 클래스로 구현할 적당한 인터페이스가 있다면 더욱 그렇다. 래퍼 클래스는 하위 클래스보다 견고하고 강력하다.