코딩하는 털보

이펙티브 자바, 아이템 19. 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 본문

Book/이펙티브 자바

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

이정인 2021. 9. 4. 16:53

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

상속을 고려한 설계와 문서화가 뜻하는 것.

  • 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 한다.
    상속용 클래스의 메서드에서 자신의 다른 메서드를 호출할 수도 있는데(자기사용) 호출되는 메서드가 재정의될 수 있다면 클래스를 상속하여 메서드를 재정의할 때 문제가 발생할 수 있다. 때문에 자기사용에 대한 내용을 API 설명에 적시해야 한다.
    백그라운드 스레드나 정적 초기화 과정에서도 메서드가 호출되어 자기사용이 발생할 수 있다.
    @implSpec 어노테이션은 자바독 도구가 API문서에 Implementation Requirements로 시작하는 메서드 내부 동작 방식 설명을 추가해준다.
  • 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅(hook)을 잘 선별하여 protected 메서드 형태로 공개해야 할 수도 있다.
    protected는 내부 구현에 해당하지만 노출하여 재정의 되었을 때 얻을 수 있는 강점(성능 개선 등)이 있다면 노출한다.
    그렇지만 역시 내부 구현에 해당하므로 그 수는 가능한 적어야 한다.
    직접 하위 클래스를 만들어서 테스트하면서 필요한 protected 메서드나 멤버를 찾는 것이 최선이다.
  • 상속용으로 설계한 클래스는 배포 전에 반드시 하위 클래스를 만들어 검증해야 한다.
  • 상속용 클래스의 생성자는 직접적으로든 간접적으로든 재정의 가능 메서드를 호출해서는 안 된다.
    하위 클래스 생성에서 의도치 않게 하위 클래스의 메서드가 호출될 수 있다. 하위 클래스 인스턴스가 초기화되기 전에 메서드가 먼저 호출되어 버리므로 충분히 프로그램 문제가 발생할 수 있다.
    private, final, static 메서드는 재정의할 수 없는 메서드이므로 안심하고 호출할 수 있다.
  • Cloneable과 Serializable을 하나라도 구현한 클래스는 확장하려는 프로그래머에게 부담을 주게 되므로 상속용 설계로 바람직하지 않다.
    하위 클래스에서 구현 하도록 하는 방법도 있다.
    clone과 readObject 메서든는 생성자와 비슷한 효과를 가지는데, 생성자 처럼 재정의 가능 메서드를 호출해서는 안된다.
    Serializable을 구현한 상속용 클래스의 readResolve와 writeReplace 메서드는 protected로 선언해야 한다.
  • 상속용으로 설계하지 않은 클래스는 상속을 금지시킨다.
    일반적인 콘크리트 클래스를 상속받는 경우 상위 클래스의 변경에 하위 클래스가 받는 영향을 예측하기 어렵다.
    가장 쉬운 방법은 final 클래스로 만들기.
    또는 모든 생성자를 private 또는 package-private으로 만들고 정적 팩토리를 제공하기.
Comments