Chapter 7 Reusing Classes
組合和繼承是復(fù)用類的兩個基本方法千贯。
7.1 組合語法
- 組合是復(fù)用的基礎(chǔ)方法之一,將對象引用置于新類中即可程奠。
- 作為成員的對象需要在使用前確保初始化丈牢。
7.2 繼承語法
- 繼承基類的子類會得到積累的所有域和方法。
基類的初始化
- 當創(chuàng)建一個子類的對象實例時瞄沙,該對象會包含基類的成員對象己沛。
- 對于基類的靜態(tài)成員,子類會繼承其引用距境。
- 為此需要確鄙昴幔基類的初始化,執(zhí)行子類的構(gòu)造函數(shù)前垫桂,會自動調(diào)用基類的默認構(gòu)造函數(shù)师幕。
- 可以使用super來顯示調(diào)用子類的其他構(gòu)造函數(shù),并將其置于構(gòu)造函數(shù)的第一句,這樣就不會自動調(diào)用父類的默認構(gòu)造函數(shù)霹粥。
7.3 代理
代理就是將一個成員對象置于所要構(gòu)造的類中(組成)灭将,并在新類中暴露了該成員對象所有的方法(繼承),以對該成員對象的方法添加其他執(zhí)行過程后控。
- IDEA可以生成代理類
7.4 結(jié)合組合和繼承
- 在實際開發(fā)中結(jié)合組合和繼承是非常常見的庙曙。
- 如果需要清理組合的成員對象,需要顯示地進行處理浩淘,如使用finally捌朴。
- 使用JAVA5的@override來確保方法覆蓋。
7.5 在組合與繼承之間選擇
- 組合計數(shù)通常用于在新類中使用現(xiàn)有類的功能张抄。
- 繼承需要滿足'is-a'的關(guān)系砂蔽,應(yīng)該更關(guān)注于接口和其實現(xiàn)。統(tǒng)一不同的代碼流程署惯。
7.6 protected關(guān)鍵字
- protected訪問權(quán)限提供了子類和包內(nèi)的訪問左驾。
- 應(yīng)該使用private來保留改變底層實現(xiàn)的權(quán)利,然后通過protected控制子類的訪問權(quán)限泽台。
7.7 向上轉(zhuǎn)型
- 繼承技術(shù)除了為新的類提供方法外什荣,更重要的方面是表現(xiàn)新類和基類之間的關(guān)系("is-a")。
- 將子類的引用轉(zhuǎn)換為父類引用的動作怀酷,稱為向上轉(zhuǎn)型稻爬。
- 向上轉(zhuǎn)型是一種安全的轉(zhuǎn)換,可以用來統(tǒng)一不同的代碼蜕依。
- 只有當需要向上轉(zhuǎn)型時才需要使用繼承(is-a關(guān)系)桅锄。
7.8 final關(guān)鍵字
Java的關(guān)鍵字final表示"不法改變的"。
final數(shù)據(jù)
- final static基本數(shù)據(jù)類型和String能夠成為編譯時常量样眠,只有一份友瘤,減輕運行負擔。
- final對象引用檐束,引用無法改變稿壁,但對象自身可以改變芝硬。
- final方法參數(shù)能夠表明方法不會改變基本數(shù)據(jù)類型的參數(shù)變量。
final方法
- final方法能夠保證無法被覆蓋修改。
- final方法在初期能夠提升編譯器方法調(diào)用的效率尼变,Java5的JVM開始基本不需要了骂租。
final類
- fiinal類無法被繼承蚊夫,其域和方法都被定義為final券时。
有關(guān)final的忠告
- 將方法指明為final,一般是類庫開發(fā)者為了不讓別人繼承這些類的一種指導(dǎo)黄选。
- 你無法猜測將來人們會怎么使用你的類蝇摸。
7.9 初始化及類的加載
- 在Java中,加載的單元是一個類(.class文件)。
- 在初次使用類的時才會對類程序代碼進行加載貌夕,包括創(chuàng)建對象和訪問static域或方法律歼。
- 加載時,所有static對象和static代碼會按書寫順序依次初始化一次蜂嗽。
繼承與初始化
再次回顧加載過程:
- 父類靜態(tài)成員自動初始化
- 父類靜態(tài)初始塊苗膝、父類靜態(tài)成員指定初始化
- 子類靜態(tài)成員自動初始化
- 子類靜態(tài)初始塊殃恒、類靜態(tài)成員指定初始化
- 父類初始塊植旧、父類成員變量指定初始化
- 父類構(gòu)造函數(shù)(若沒有在構(gòu)造器里super指定,調(diào)用無參構(gòu)造函數(shù))
- 子類初始塊离唐、子類成員變量指定初始化
- 子類構(gòu)造函數(shù)
- 當在一個類文件上運行Java時病附,首先試圖訪問該類的main()方法(static)。
- 于是加載器開始啟動并通過package對應(yīng)os目錄找到編譯代碼(.class文件)亥鬓。
- 開始加載時完沪,編譯器先通過extends得知基類的存在,于是優(yōu)先加載基類嵌戈。
- 基類的static初始化開始被執(zhí)行覆积,按書寫順序進行靜態(tài)域的初始化。
- 然后開始進行子類的static初始化(因為子類的static域可能依賴于基類)熟呛。
- 至此宽档,類已加載完畢沒開始進行對象創(chuàng)建的過程。
- 首先對象的基本類型數(shù)據(jù)設(shè)為默認值(自動初始化)庵朝,對象引用設(shè)為null(二進制0)吗冤。
- 之后開始執(zhí)行基類的構(gòu)造函數(shù)(自動調(diào)用默認構(gòu)造函數(shù),或者通過super指定)九府,然后子類構(gòu)造函數(shù)其他部分椎瘟。
7.10 總結(jié)
- 繼承和組合都是復(fù)用類(代碼)的基本方式,優(yōu)先考慮組合侄旬,只有當需要向上轉(zhuǎn)型的時候才用繼承肺蔚。
- 程序開發(fā)是一個增量過程,開發(fā)項目時無法知道所有的答案儡羔,所以將項目視作一種有機的宣羊、進化這的生命體而去培養(yǎng)(并通過訪問控制機、final對其進化進行一定的限制)笔链。