상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 사용하는지 문서로 남겨야한다.
그런데, 이는 좋은 API 문서란 '어떻게' 가 아닌 '무엇' 을 하는지 설명해야한다 라는 격언에 대조적이다.
상속은 캡슐화을 깨뜨리기 때문. 어쩔 수 없다.
클래스 내부 동작 중 끼어들 수 있는 훅을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 있다.
재정의 될 곳을 미리 정의하고, 하위 클래스에서 메서드 재정의를 쉽게 할 수 있도록 돕는다.
상속용 클래스의 생성자는 재정의가 가능한 메서드를 절대 호출해서는 안된다.
하위 클래스에서 super 를 통해 생성자를 호출하게 될 때, 초기화되지 않은 하위 클래스의 필드값을 이용한 재정의된 메서드가 동작하여 의도치 않게 동작할 수 있다.
상속용 클래스를 구현하는 것은 제약도 많고, 엄청난 노력이 필요하다.
따라서 일반적인 클래스의 경우 상속을 금지해야한다.
클래스를 final 로 설정한다.
모든 생성자를 private, package-private로 설정하고 정적 팩터리 메서드를 만들어준다.
참고.
상속을 클래스를 시험하는 방법은 직접 하위 클래스를 만들어보는 것이 유일하다.
생성자에 재정의 가능 메서드를 호출하지 못하는 제약이 있듯, clone, readObject를 구현할 때도 마찬가지이다.
재정의가 가능한 메서드를 클래스 내부에서 아예 사용하지 않고 문서로 남긴다면 상속해도 그리 위험하지 않은 클래스를 만들 수 있다. (기능은 아쉬울 수도)
재정의 가능 메서드의 본문 코드를 모두 private 도우미 메서드로 옮기로 각 메서드는 각각의 도우미 메서드를 호출하여 내부적으로도 재정의 가능 메서드를 호출할 수 있도록 할 수도 있다.