專門為繼承而寫的 class,必須提供文件來說明可覆寫的方法,文件中說明 clsdd 的方法及 constructor 與 non-final 及 public 或 protected 方法的調用,像是調用順序、結果會如何影響處理過程等等。
對於為繼承而寫的 class,唯一的測試方法就是利用 subclass。在廣泛地被使用前,應進行測試,一旦釋出版本後,若在後續版本更改其規則,相當不容易,因為要修改的部分有機會已經被開發者實作或是調用。
為允許繼承,需遵守以下的限制與規範,無論直接或間接,constructor 不能調用可以被覆寫的方法。super class 的 constructor 會先執行,若是 subclass 覆寫的方法在 super class constructor 中調用,會產生不如預期的狀況,下面提供一範例,SubClass 覆寫在 constructor 中會用到的方法。main 會輸出兩個結果,第一個為 0,第二個為正確時間,第一個是 super class constructor 調用 forOverride 印出,因為 subclass constructor 尚未執行,自然會是 0。
public class SuperClass {
public SuperClass () {
forOverride();
}
public void forOverride() { }
}
public class SubClass extends SuperClass {
private final long time;
SubClass() {
time = System.currentTimeMillis();
}
@Override
public void forOverride() {
System.out.println(time);
}
public static void main(String[] args) {
SubClass c = new SubClass();
c.forOverride();
}
}
實作 Cloneable 或 Serializable 會對繼承造成一些麻煩,clone 及 readObject 它們的行為類似 constructor,所以一樣不能調用可覆寫的方法,要實作 Serializable 必須將 readResolve 或 writeReplace 方法變成 protected,但這樣就是因為繼承而將實作細節暴露出來。對於不是為繼承而開發的 class,應禁止它被繼承,最簡單的方式就是將 class 宣告為 final,另一種方式是將 constructor 改為 private 或 package-private,再用 static factory 來取代。
轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2020/07/effective-java-19-extends-javadoc.html
沒有留言:
張貼留言