類和接口是Java程序設計語言的核心,也是Java語言的基本抽象單元。Java語言提供了許多強大的基本元素,供程序員用來設計類和接口。
第一條:使類和成員的可訪問性最小
一個設計良好的模塊,最重要的一點是要對於外部模塊隱藏關鍵的實現細節,只外漏該外拋的方法。模塊之間只通過它們之間的API進行通訊訪問。在Java的程序設計語言中,通過訪問控制來實現類、接口和成員的可訪問性限制,這些修飾符有public、protected和private。類和接口的修飾符只能是public或默認
如果一個包級私有的頂層類只在某個類中內部使用,可以考慮把它設計未嵌套內部類。對於成員(域、方法、嵌套類和嵌套接口)有四中可能的訪問級別:
第二條:在共有類中使用訪問方法來替代公有域
由於這種類的數據可以被直接訪問,這些類沒有提供封裝功能,所以如果沒有改變API接口,就無法改變它的數據行為,一般我們的建議是如果類可以在它所在的包外被訪問,就應該主動提供訪問的方法來訪問。
第三條:使可變性最小化
不可變類只是實例不能被修改的類,每個實例中包含的字段信息都應該在實例創建的時候進行指定,比如String。不可變類更加易於設計、實現和使用,不容易出錯。為了使類成為不可變類,一般遵循下面五條規則:
不要提供任何會修改對象狀態的方法
保證類不會被繼承擴展
使所有的域都是final類型的
使所有的域都是私有的
確保對於任何可變組件的互斥訪問
第四條:組合優先於繼承
繼承是代碼重用的有力手段,但是在Java程序開發彙總,我們更推薦在包的內部使用繼承,主要是因為這種方式相對於包外的繼承更安全。
與通過組合形式的方法調用不同,繼承打破了封裝性,子類依賴其父類中特定的功能細節。
第五條:接口優於抽象類
Java程序中提供了接口和抽象類來實現多個實現的類型。明顯的區別是抽象類中允許包含某些方法的實現,接口中是不允許的。Java中的類是單繼承,搜易抽象類作為類型定義會收到極大的限制。使用接口主要有以下好處:
現有類可以很容易被更新,以實現新接口
接口的定義是混合類型的立項選擇
接口允許我們構造非層次結構的類型框架,比如一個人是歌唱家又是作曲家。
我們知道通過接口的多實現特性可以構建多層次的類結構,我們同時也可以通過對每個接口都提供一個抽象的骨架實現類,把接口和抽象類的優點結合起來。
第六條:接口只用於定義類型
在我們開發中,我們一定出現過在接口中定義靜態常量的情況,這種接口稱之為常量接口。
常量接口是對接口的不恰當使用。在Java中如果我們要定義常量,可以使用枚舉的方式進行定義。或者通過不可實例化的工具類來導出這些常量,避免通過實現綁定到具體的類上。
第七條:類層次優於標籤類
類層次在前面我們已經知道了,那什麼是標籤類呢?如下面:
那麼針對標籤類我們如何優化呢?這裡就可以使用到層次類來進行優化,將標籤類轉換為層次類首先要為標籤類中的每個方法定義一個包含該方法的抽象類,比如area方法。接下來就是為原始標籤類定義根類的具體子類。
通過上面的優化體驗上來說,就是規劃好累的層次,精簡類的職能。
第八條:優先考慮靜態成員類
定義在一個類中的內部類稱之為嵌套類。嵌套類存在的目的是為了輔助它的外圍類,如果嵌套類出現用於外部其它環境中,它就應該被定義成頂層類。嵌套類有四中:靜態內部類、非靜態成員類、匿名類和局部類。除了靜態內部類外,其它的三種都被稱之為內部類。
靜態成員類是最簡單的一種嵌套類。與普通的類相差不大,只是定義在另一個類的內部,它可以訪問外圍類的所有成員,包含那些私有成員,它和靜態成員一樣。
非靜態成員類的每個實例都隱藏著與外圍類的一個實例引用。非靜態成員類可以調用外圍類的方法,或者通過修飾後的this獲取外圍類的實例引用。如果嵌套類的實例可以在它的外圍類的實例之外獨立存在,這個類就必須是靜態成員類。
總結
通過這一章的接口和類的比較,增加了對接口和類的更深入瞭解,同時對類的設計有了更進一步的思考。主要體現在以下幾個方面:
類和接口的設計要儘量封閉,減少外拋的接口,使之可訪問性降低,更加穩定;
對公有域(成員變量)儘量使用方法來進行獲取設置,不要直接進行操作,以便後續可以豐富完善;
類和接口設計要精簡、幹練,避免冗餘形成標籤類;
多使用接口進行豐富類的功能,降低類的層次;
內部類的作用是為了輔助外圍內,不要本末倒置;
閱讀更多 Andoter的學習筆記 的文章