《Effective Java 2nd》第4章 类和接口
第4章 類和接口
第13條: 使類和成員的可訪問性最小化
盡可能使每個(gè)類或者成員不被外界訪問。提供盡可能小的訪問級(jí)別。
final維持字段不可變性,字段要么是基本類型的、要么是指向不可變對(duì)象的引用。
如果final包含可變對(duì)象的引用,雖然引用不能被修改,但是引用對(duì)象的內(nèi)部卻可以被修改。
注意:長(zhǎng)度非0的數(shù)組總是可變的。
?
第14條:在公有類中使用訪問方法而非公有域
?
第15條:使可變性最小化
講了不可變類的相關(guān)內(nèi)容。
不可變類:實(shí)例不能被修改的類。實(shí)例化后,實(shí)例中包含的內(nèi)部信息在整個(gè)生命周期中固定不變。
如何使類不可變
1)不提供任何修改對(duì)象狀態(tài)的方法
2)保證類不會(huì)被擴(kuò)展。如將類聲明為final
3)使所有的域都是final的
4)所有的域都是私有的
5)對(duì)任何可變域(指指向可變對(duì)象的域),使用保護(hù)性拷貝技術(shù)
不可變對(duì)象的好處:線程安全,可以自由共享
不可變類的唯一缺點(diǎn):每個(gè)不同的值都要有一個(gè)單獨(dú)的對(duì)象,比如String s = ”aaa", String s2 = "bbb"。
因不可變類的缺點(diǎn),可以提供一個(gè)可變配套類,比如對(duì)String來說有StringBuilder
?
第16條:復(fù)合優(yōu)先于繼承
這里的繼承指的是一個(gè)類擴(kuò)展另一個(gè)類的時(shí)候,不含接口繼承(類實(shí)現(xiàn)接口、接口實(shí)現(xiàn)接口)。
只有當(dāng)兩個(gè)類A和B,兩者之間確實(shí)存在is a關(guān)系的時(shí)候,才適合用繼承。問自己:每個(gè)B都是A嗎?
?
第17條:要么為繼承而設(shè)計(jì),并提供文檔說明,要么就禁止繼承
如果某個(gè)類是為繼承而設(shè)計(jì)的,在類文檔中應(yīng)該明確描述覆蓋每個(gè)方法所帶來的影響。
?
第18條:接口優(yōu)先于抽象類
接口和抽象類區(qū)別
1)抽象類允許包含某些方法的實(shí)現(xiàn),接口不允許。
2)實(shí)現(xiàn)抽象類,類必須成為抽象類的子類。但是,任何一個(gè)類均可實(shí)現(xiàn)一個(gè)接口,不管這個(gè)類位于類繼承層次的哪個(gè)位置。
?
接口的好處:
1)現(xiàn)有類很容易通過實(shí)現(xiàn)新的接口,實(shí)現(xiàn)新的功能,不管這個(gè)類位于類繼承層次的哪個(gè)位置。
2)接口是定義mixin類型的理想原則。
mixin類型:指類除了實(shí)現(xiàn)它的基本功能外,還可以實(shí)現(xiàn)mixin類型,以表明它提供了某種可供選擇的功能。
舉例:Comparable是mixin接口,某個(gè)類實(shí)現(xiàn)后代表具備排序功能。
3)類允許我們構(gòu)造非層次接口的類型框架。
舉例:singer接口代表歌唱家,songwriter接口代表作曲家,我們完全可以聲明一個(gè)SingerSongwriter接口擴(kuò)展上面兩個(gè)接口,代表同時(shí)歌唱家也是作曲家。
?
接口不允許含方法的實(shí)現(xiàn)。但是可提供個(gè)抽象的骨架實(shí)現(xiàn)類。接口用于定義類型,但是骨架實(shí)現(xiàn)類用于接口接口實(shí)現(xiàn)相關(guān)工作。
舉例:集合框架中的AbstractCollection、AbstractSet等都是骨架實(shí)現(xiàn)類。
?
第19條:接口只用于定義類型
講了不要使用常量接口。常量接口類似于下面。
public interface XXXXContants {static final double XXXXXX = 1.1222;static final double YYYYYY = 1.3222; }常量接口的壞處:在版本迭代時(shí),某個(gè)類不再使用這些常量了,仍必須實(shí)現(xiàn)這個(gè)接口,以確保二進(jìn)制兼容性。
?
如何定義常量。
1)常量與某個(gè)類或接口緊密相關(guān),定義在這個(gè)類后接口中。
舉例:Integer中的常量MIN_VALUE
2)使用枚舉類型
3)使用常量工具類。
?
第20條:類層次優(yōu)于標(biāo)簽類
?
?
第21條:用函數(shù)對(duì)象表示策略
Java中沒有函數(shù)指針,但是可以用對(duì)象引用實(shí)現(xiàn)同樣的功能,這樣的實(shí)例稱為函數(shù)對(duì)象,舉例:Comparator類定義了排序策略。
?
第22條:優(yōu)先考慮靜態(tài)成員類
講了嵌套類,主要是各種內(nèi)部類的使用場(chǎng)景。
嵌套類有4種:
1)內(nèi)部類:靜態(tài)內(nèi)部類、非靜態(tài)內(nèi)部類、匿名內(nèi)部類
2)局部類
?
靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類常見用法是用作輔助類。舉例:Calculator內(nèi)部聲明一個(gè)靜態(tài)枚舉類Operation用于表示計(jì)算器支持的各種操作。Calculator.Operation.PLUS,Calculator.Operation.MINUS。
私有靜態(tài)內(nèi)部類的常見用法是用來代表外部類所代表的對(duì)象的組件。舉例:Map的Entry。
?
非靜態(tài)內(nèi)部類
非靜態(tài)內(nèi)部類的常見用法是定義一個(gè)Adapter。舉例:Map接口使用非靜態(tài)內(nèi)部類來實(shí)現(xiàn)集合視圖(collection view),如keySet、entrySet等。
?
靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類的區(qū)別
1)靜態(tài)內(nèi)部類可看做是普通的類,只是碰巧聲明在另一個(gè)類的內(nèi)部??梢悦撾x外部類的實(shí)例獨(dú)立存在。
2)非靜態(tài)內(nèi)部類的每個(gè)實(shí)例都與外部類的一個(gè)實(shí)例向關(guān)聯(lián),當(dāng)非靜態(tài)內(nèi)部類被創(chuàng)建時(shí),這種聯(lián)系建立起來。
?
匿名內(nèi)部類
匿名內(nèi)部類常見用法
1)創(chuàng)建函數(shù)對(duì)象。舉例:排序時(shí),創(chuàng)建匿名Comparator實(shí)例,傳遞給sort方法。
2)創(chuàng)建過程對(duì)象。舉例:Runnable、Thread
?
局部類
在任何可聲明局部變量的地方,都可聲明局部類。
轉(zhuǎn)載于:https://www.cnblogs.com/yeyang/p/10461301.html
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的《Effective Java 2nd》第4章 类和接口的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2019.03.02
- 下一篇: 在Java8的foreach()中不能b