[Effective Java 3rd] 아이템18~19

Mr.Sir·2022년 7월 7일
0

Effective Java 스터디

아이템18 상속보다는 컴포지션을 사용하라

상속은 캡슐화를 깨뜨린다.

상위 클래스와 하위 클래스를 모두 같은 프로그래머가 통제하는 패키지 안에서라면 상속도 안전한 방법이다. 하지만 일반적인 구체 클래스를 패키지 경계를 넘어,
즉 다른 패키지의 구체 클래스를 상속하는 일은 위험하다.

메서드 재정의가 원인인 문제들을 회피하기 위해..

<컴포지션>
기존 클래스를 확장하는 대신, private 필드로 기존 클래스의 인스턴스를 참조하게 한다. 기존 클래스가 새로운 클래스의 구성요소로 쓰인다는 뜻.
새 클래스의 인스턴스 매서드들은 기존 클래스의 대응하는 메서드를 호출해 그 결과를 반환한다. 이 방식을 전달이라 하며, 새 클래스의 메서드들을 전달메서드라 부른다. 그 결과 새로운 클래스는 기존 클래스의 내부 구현 방식의 영향에서 벗어나며, 심지어 기존 클래스에 새로운 메서드가 추가되더라도 전혀 영향받지 않는다.
한 번만 구현해두면 어떠한 구현체라도 계측할 수 있으며 기존 생성자들과도 함께 사용할 수 있다.
컴포지션과 전달의 조합은 넓은 의미로 위임이라고 부른다.
단 엄밀히 따지면 래퍼 객체가 내부 객체에 자기 자신의 참조를 넘기는 경우만 해당.

상속은 반드시 하위 클래스가 상위 클래스의 진짜 하위 타입인 상황에서만 쓰여야 한다.

컴포지션 대신 상속을 사용하기로 결정하기 전에.

확장하려는 클래스의 API에 아무런 결함이 없는가?
결함이 있다면, 이 결함이 여러분 클래스의 API까지 전파돼도 괜찮은가?
컴포지션으로는 이런 결함을 숨기는 새로운 API를 설계할 수 있지만 상속은 결함까지 그대로 승계한다.

상속은 강력하지만 캡슐화를 해치며 상위 클래스와 하위 클래스가 순수한 is-a 관계일 때만 써야 한다. 상속의 취약점을 피하려면 상속 대신 컴포지션과 전달을 사용하자.

     


     

아이템19 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라

상속을 고려한 설계와 문서화란 정확히 무엇인가?

상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다.
클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅(hook)을 잘 선별하여 protected메서드 형태로 공개해야 할 수도 있다.

상속용으로 설계한 클래스는 배포 전에 반드시 하위 클래스를 만들어 검증해야 한다.

상속용 클래스의 생성자는 직접적으로든 간적접으로든 재정의 가능 메서드를 호출해서는 안 된다.
clone, readObject 모두 재정의 가능메서드를 호출해서는 안 된다.

Serializable을 구현한 상속용 클래스가 readResolve나 writeReplace메서드를 갖는다면 이 메서드들은 private이 아닌 protected로 선언해야 한다.

상속용으로 설계하지 않은 클래스는 상속을 금지한다.

클래스를 final로 선언하거나, 모든 생성자를 private이나 package-private으로 선언하고 public 정적 팩터리를 만들어주는 방법이 있다.

profile
Deepveloper

0개의 댓글