2020/07/21

[筆記] Effective Java #19 設計繼承一併提供文件,否則不要使用繼承

Effective Java 3rd 簡體中文版筆記 #19 設計繼承一併提供文件,否則不要使用繼承
專門為繼承而寫的 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 會對繼承造成一些麻煩,clonereadObject 它們的行為類似 constructor,所以一樣不能調用可覆寫的方法,要實作 Serializable 必須將 readResolvewriteReplace 方法變成 protected,但這樣就是因為繼承而將實作細節暴露出來。
對於不是為繼承而開發的 class,應禁止它被繼承,最簡單的方式就是將 class 宣告為 final,另一種方式是將 constructor 改為 private 或 package-private,再用 static factory 來取代。

轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2020/07/effective-java-19-extends-javadoc.html

沒有留言:

張貼留言