코딩하는 털보

이펙티브 자바, 아이템 18. 상속보다는 컴포지션을 사용하라 본문

Book/이펙티브 자바

이펙티브 자바, 아이템 18. 상속보다는 컴포지션을 사용하라

이정인 2021. 9. 4. 12:48

이펙티브 자바, 아이템 18. 상속보다는 컴포지션을 사용하라

동일한 패키지 안에서의 상속이나 확장할 목적으로 설계되었고 문서화도 잘 된 클래스의 상속은 안전하다.
그러나 일반적인 콘크리트 클래스를 패키지 경계를 넘어서 다른 패키지의 콘크리트 클래스를 상속하는 일은 위험하다.

메서드 호출과 달리 상속은 캡슐화를 깨뜨린다. 다르게 말하면, 상위 클래스가 어떻게 구현되느냐에 따라 하위 클래스의 동작에 이상이 생길 수 있다.
특히 상위 클래스의 메서드를 재정의해서 사용했을 때 문제가 발생하기 쉽다.
또는 하위 클래스에서 새로운 메서드를 만들때도 상위 클래스의 변경으로 인한 영향이 없다고 할 수는 없다.

상속 대신 컴포지션을 사용하자.
기존 클래스를 확장하는 대신 새로운 클래스에서 private 필드로 기존 클래스의 인스턴스를 참조하게 하자. 컴포지션을 사용하면 기존 클래스의 내부 변화에 영향받지 않는다.
새로운 클래스의 메서드에서는 기존 클래스의 메서드를 호출한다(전달 메서드). 전달과 컴포지션의 조합을 '위임'이라고도 한다.
위임을 통해서 래퍼클래스를 만들 수 있다. 래퍼 클래스는 콜백 프레임워크와 어울리지 않는다는 것 외에는 단점이 거의 없고 견고하고 안전하다.(데코레이터 패턴)

상속은 반드시 하위 클래스가 상위 클래스의 '진짜' 하위 타입인 상황에서만 쓰여야 한다. (B is a A 인 경우에만 B extends A)
컴포지션을 써야 할 상황에서 상속을 사용하면 내부 구현을 불필요하게 노출하여 API가 내부 구현에 묶이게 된다. 클라이언트가 이 노출된 내부에 접근할 수 있기 때문에 혼란을 유도할 수도 있고 하위 클래스의 불변식을 깨뜨릴수도 있다.
상속은 상위 클래스의 결함까지도 하위 클래스에 승계한다.

Comments