-
Item 19: Design and document for inheritance or else prohibit it독서/Effective Java 2021. 12. 19. 16:17
상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라.
효과 문서화
클래스는 메서드 재정의의 효과를 정확하게 문서화해야 한다. 클래스는 재정의 가능한 메서드를 호출할 수 있는 모든 상황을 문서화해야 한다.
JavaDoc 태그인 @implSpec를 사용하면 API 문서에 "Implementation Requirements" 절(내부 동작 방식 설명)을 생성해준다.
이 문서는 iterator 메서드를 재정의하면 remove 메서드의 동작에 영향을 주고, 또한 iterator 메서드가 반환하는 Iterator의 동작이 remove 메서드의 동작에 어떻게 영향을 미치는지 정확하게 설명한다.
Hook
안전하게 하위 분류될 수 있도록 클래스를 문서화하려면 지정되지 않은 상태로 두어야 하는 구현 세부 정보를 설명해야 한다.
상속을 위한 설계에는 자체 사용 패턴을 문서화하는 것 이상이 포함된다. 프로그래머가 과도한 고통 없이 효율적인 하위 클래스를 작성할 수 있도록 하기 위해 클래스는 신중하게 선택한 protected 메서드 또는 드문 경우지만 protected 필드의 형태로 내부 작업에 대한 Hook를 제공해야할 수 있다.이 메서드는 List 구현의 최종 사용자에게 관심 없이, 하위 클래스가 하위 목록에 대한 빠르고 명확한 메서드를 제공하기 쉽도록 하기 위해서만 제공된다. removeRange 메소드가 없으면 하위 클래스는 하위 목록에서 clear 메소드를 호출하거나 전체 하위 목록 메커니즘을 처음부터 다시 작성할 때 2차 성능과 관련이 있어야 한다.
상속용 클래스의 생성자는 재정의 가능 메서드를 호출해서는 안 된다.
public class Super { public Super() { overrideMe(); } public void overrideMe() { } } public final class Sub extends Super { private final Instant instant; Sub() { instant = Instant.now(); } @Override public void overrideMe() { System.out.println(instant); } public static void main(String[] args) { Sub sub = new Sub(); sub.overrideMe(); } }
하위 클래스의 생성자보다 상위 클래스의 생성자가 먼저 호출되는데, 상위 클래스의 생성자에서 하위 클래스의 재정의된 메서드를 호출하여 null값이 출력되었다.
상속용으로 설계하지 않은 클래스는 상속을 금지하자.상위 클래스가 상속용으로 설계되지 않은 경우 클래스에 변화가 생길 때마다 하위 클래스에 오작동을 일으킬 수 있다. 상속용으로 설계되지 않았다면 상속을 금지해야 한다.
- 클래스를 final로 선언한다.
- 모든 생성자를 private나 default로 선언 -> public static factory를 만든다.
정리
클래스 내부에서 스스로 어떻게 사용하는지를(자기 사용 패턴) 모두 문서로 남겨야 하며, 문서화한 것은 그 클래스가 쓰이는 한 반드시 지켜야 한다.
다른 프로그래머가 하위 클래스를 만들 수 있도록 일부 메서드를 protected로 제공해야 할 수 있다.
클래스를 확장해야 할 명확한 이유가 없다면 상속을 하지말자.
'독서 > Effective Java' 카테고리의 다른 글
Item 21: Design interfaces for posterity (0) 2021.12.26 Item 20: Prefer interfaces to abstract classes (0) 2021.12.19 Item 18: Favor composition over inheritance (0) 2021.12.19 Item 17: Minimize mutability (0) 2021.12.19 Item 16: In public classes, use accessor methods, not public fields (0) 2021.12.19