메서드를 재정의하면 어떤 일이 일어나는지를 정확히 정리하여 문서로 남겨야 합니다. 달리 말하면 재정의 할 수 있는 메서드들을 내부적으로 어떻게 이용하는지 문서로 남겨야 합니다.
API문서의 메서드 설명 끝에 "Implementation Requirements"로 시작하는 절이 바로 내부 동작을 설명하는 곳입니다.
이는 메서드 주석에 @implSpec
태그를 붙여주면 자바독 도구가 생성해줍니다.
@implSpec
태그는 자바8에 처음 도입되었습니다. 이 태그를 활성화하려면 명령줄 매개변수로 -tag "implSpec:a:Implementationo Requirements:"
를 지정해주면 됩니다.
문서화 말고도 고려해야 할 것들이 더 있습니다.
- 클래스의 내부 동작 과정 중간에 끼어들 수 있는 훅(hook)을 잘 선별하여 protected 형태로 공개해야 할 수도 있습니다.
- 상속용 클래스를 시험하는 방법은 직접 하위 클래스를 만들어 보는 것이 '유일'합니다. 그러니 상속용 클래스는 배포전에 반드시 하위 클래스를 만들어 검증합니다.
- 상속용 클래스의 생성자는 직, 간접적으로 재정의 가능 메서드를 호출해서는 안됩니다.(private, final, static 메서드는 재정의가 불가능하니 호출해도 괜찮습니다.)
- Cloenable과 Serializable 중 하나라도 구현한 클래스를 상속용으로 설계하는 것은 일반적으로 좋지 않습니다.
- clone과 readObject 모두 직, 간접적으로 재정의 가능 메서드를 호출해서는 안됩니다.
- Serializable를 구현한 상속용 클래스가 readResolve나 writeReplace 메서드를 갖는다면 이 메서드들은 protected로 선언해야 합니다.
이렇게 고려할 사항이 많다는 것은 상속용이 아닌 클래스를 상속 했을 경우 많은 문제가 생길 수 있기 때문입니다. 따라서 상속용으로 설계하지 않은 클래스는 상속을 금지해야 합니다.
상속을 금지하는 방법은 두 가지 입니다.
- 클래스를 final로 선언
- 모든 생성자를 private이나 default로 선언하고 정적 팩토리 메서드를 제공
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
[Effective Java] Item21. 인터페이스는 구현하는 쪽을 생각해 설계 (0) | 2022.06.04 |
---|---|
[Effective Java] Item20. 추상 클래스보다는 인터페이스 (0) | 2022.06.04 |
[Effective Java] Item18. 상속보다는 컴포지션 (0) | 2022.05.29 |
[Effective Java] Item17. 변경 가능성을 최소화 (0) | 2022.05.29 |
[Effective Java] Item16. public클래스에서는 접근자 메서드 사용 (0) | 2022.05.29 |