Java ‐ 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라[Effective Java Item 19] - dnwls16071/Backend_Summary GitHub Wiki
상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라
- 상속용 클래스는 재정의할 수 있는 메서드들을 내부적으로 어떻게 동작하는지 문서로 남겨야 한다.
- 호출되는 메서드가 재정의 가능한 메서드라면 그 사실을 호출하는 메서드 API 설명에 명시해야 한다.
- 상속은 캡슐화를 해치기 때문에 이 문서화는 반드시 해야하는 작업이며, 클래스를 안전하게 상속할 수 있도록 하려면 내부 구현 방식을 설명해야 한다.
Implementation notes 하위에 문서로 기술하고 있다.
public class Super {
public Super() {
overrideMe(); // 생성자가 재정의 가능한 메서드를 호출한다.
}
public void overrideMe() {
}
}
public final class Sub extends Super {
private final Instacnce instacnce;
Sub() {
instacnce = Instacnce.now(); // create instance in constructor
}
@Override
public void overrideMe() {
System.out.println(instacnce);
}
public static void main(String[] args) {
Sub sub = new Sub();
/*
* instance 가 null / instance 두 개 출력 된다
* 상위 클래스의 생성자는 하위 클래스의 생성자가 인스턴스 필드를 초기화하기 전에 overrideMe 호출
* */
sub.overrideMe();
}
}
- 상속용 클래스 생성자는 직접적으로든 간접적으로든 재정의 가능한 메서드를 호출해서는 안 된다.
- 위 규칙을 지키지 않으면 프로그램의 오작동을 일으킬 수 있다.
- 상위 클래스 생성자가 명시되지 않았다하더라도 하위 클래스 생성자보다 먼저 실행되기 때문이다.
- 상속용으로 설계하지 않은 클래스는 상속을 금지하는 것이다.
- 클래스에 final 키워드를 붙이거나 모든 생성자를 private, package-private으로 선언하고 public 정적 팩토리를 만드는 것이다.
- 굳이 상속을 허용하겠다면 문서를 만들어라.