四。類和介面
第12條:使類和成員的可訪問能力最小
為了更好的實現資訊隱藏,降低各模組的耦合度,盡可能地降低類和成員的訪問能力是必須的。有一點特別關鍵,就是公有的靜態final域幾乎全部是錯誤的。客戶可以修改這樣的成員陣列,應該改為私有的才是安全的。
第13條:支援非可變類
使乙個類成為非可變類需要做到以下5點:
1。不能提供任何會修改物件的方法
2。保證沒有可被子類覆寫的方法,可以通過使這個類為final來達到
3。使所有的成員變數都是final
4。使所有的成員變數都為私有
5。保證對於任何可變元件互斥訪問
使乙個類成為非可變類的的優點:
1。非可變類通常比較簡單,呵呵,這點很明顯,他只有乙個狀態
2。非可變類通常是執行緒安全的
3。非可變類為其他物件提供了很多構件
4。非可變類最大的缺點在於對於每個不同的值(或者說狀態),都要求乙個單獨的物件,在某些情況下你需要建立非常多的物件,效能上有很大影響
儘管如此,盡力使每乙個類成為非可變類應該是你追求的目標。
第14條:復合優於繼承
昨天在看《物件導向程式設計導論》,提到「子類」和「子型別」是不同的,替換原則只適合於子型別關係,而一般程式語言只是考慮了子類關係,子類說明了新類是繼承自父類,而子型別強調的是新類具有父類一樣的行為(未必是繼承)。那麼,什麼時候才應該使用繼承?那就是符合子型別關係的時候,或者一般所說的」is a"關係,你必須保證新類的行為與父類完全一致!!!在任何使用父類的場合,新類應該表現一樣的行為。
繼承是oop最重要的概念之一,但是繼承也破壞了「封裝性」,子類的實現要依賴於父類的實現細節。所以,除了上面提到的情況外,你應該盡量用復合取代繼承。(在覆寫equals()方法也提到了這點)否則都屬於繼承的濫用,技術的濫用已經屢見不鮮了。
第15條:要麼專門的設計,以使用繼承,並給出文件說明,要麼禁止繼承
這點跟上面一點強調的一樣。如果你要使用繼承,請做好設計,在建構函式,clone(),readsolve()方法中不要呼叫任何可變的方法,並寫出詳細的文件說明。其實最好的情況,還是不使用的好!
第16條:介面優於抽象類
介面是定義具有多個實現的型別的最佳途徑,這點很明顯,每個具體類實現介面不同。如果當演化的容易性比靈活性更重要的時候,你應該使用抽象類。如,你要往抽象類中增加乙個方法,任何實現這個抽象類的子類就自動具有這乙個方法,而介面則不能,所有公有的介面的設計要非常謹慎,並保證盡力對外不做修改。在使用介面的時候,一般都設計乙個抽象類作為「骨架」,這個抽象類應該盡可能地小,只保留有最基本的功能。
第17條:介面只是被用於實現型別
你實現了乙個介面,就代表這個類是該介面的型別。在應用我們經常看到在介面中定義靜態公有的常量,這其實是對介面的誤用(汗,我是這種錯誤的典型),如
public inte***ce constants這樣的形式完全是錯誤的,應該使用乙個不能產生例項的類來代替
public class constants //建構函式為私有
pulic static final int one=1;
第18條:應該優先考慮靜態內部類
非靜態類總是和外部類的例項相聯絡,應該盡量使用靜態內部類。
Effective Java 學習筆記 6
及時消除不使用的物件的引用,理論上,帶有記憶體管理的語言是不存在記憶體洩漏的,但是如果對物件的操作不當,也是可能會造成記憶體洩漏.如有乙個stack,其pop函式如下.public object pop if element.length 0 return null return element s...
Effective Java 學習筆記(5)
盡量復用物件,而不是建立新的物件,特別是當乙個物件是immutable 不可改變 的時候。如string物件,string s new string string 千萬不要這樣做,因為這裡實際上建立了兩個物件。要避免出現這樣的情況,1是可以用靜態工廠函式,來解決,如類庫中的boolean.value...
Effective Java 學習筆記 6
及時消除不使用的物件的引用,理論上,帶有記憶體管理的語言是不存在記憶體洩漏的,但是如果對物件的操作不當,也是可能會造成記憶體洩漏.如有乙個stack,其pop函式如下.public object pop if element.length 0 return null return element s...