Java編程思想讀書筆記
代理很有意思,(我們姑且使用導出類和基類這樣的字眼,但要清楚我們不是在討論繼承里面的關鍵詞)在導出類里保存一個基類的對象,然后用自己的方法對該基類的種種方法進行包裝。
如何決定使用哪種方法復用類呢?is-a就繼承,has-a就用組合。而且,組合比繼承總體上使用更廣泛、代價更小。
向上轉(zhuǎn)型
這個就牛逼了,第八章,第九章,第十章都與此密切相關?赐瓯緯笥∠笞钌畹木褪窍蛏限D(zhuǎn)型了。
使用final的原因有很多種,一定要弄清楚為什么使用final,是由于設計還是效率。
final作用于數(shù)據(jù)的時候:final作用在基本對象比如int上,該值就成為不可改變的,一旦被初始化就無法再被更改,但是作用在普通的對象引用的時候,final使引用恒定不變,但是引用指向的對象是可變的。編譯器需要我們確保final對象一定要被初始化,我們可以通過在構造器中初始化他們,以達到相對自由的效果(稱為空白final,我認為這個名字容易讓人誤解)。java允許在參數(shù)列表中以聲明的方式將參數(shù)指明為final,這一特性主要用來向匿名內(nèi)部類傳遞數(shù)據(jù)(這很重要)。
final作用于方法的時候,說明作者想保持該方法在繼承的過程中不被改變,并且不被覆蓋。同時,被final修飾的方法會被關閉“動態(tài)綁定”,這樣編譯器就會為final方法調(diào)用生成“有限”有效的代碼。之所以說有限,是因為隨著編譯器的牛逼,它生成的代碼越來越有效。
final作用于類的時候,即是作者聲明對該類的設計不允許任何繼承。
學習得更深入一些,可能對以下事實感到有興趣:java中所有的事物都是對象,每個類的編譯代碼都存在于電腦中的文件夾里(文件夾的層次根據(jù)反轉(zhuǎn)域名得到),該文件只有在需要使用程序代碼時才被加載。具體的說,就是“類在其任何static成員函數(shù)(包括構造函數(shù))被訪問時加載”。第八章 多態(tài)
多態(tài)的重要基本原理就是向上轉(zhuǎn)型:繼承允許將對象視為它自己本身的類型或其基類型加以處處理。
將一個方法調(diào)用和一個方法主題關聯(lián)起來稱為綁定,java中所有的方法都是后期綁定(除了static方法和final方法),所以我們可以編寫只與基類打交道的程序代碼,并且這些代碼對所有的導出類都可以正確運行。
(為什么static不動態(tài)綁定:因為static方法的主要用法就是用類名.方法名這樣的方式來調(diào)用,不存在“發(fā)送消息給某個對象,讓對象判斷自己怎么做”這樣的情況。
為什么final不動態(tài)綁定:這是早期final的一種用法,由程序員指定某方法為final,意味著程序員明了動態(tài)綁定的機制,并且聲明該方法不需要動態(tài)綁定,這樣可以獲得更好的性能。這種用法已經(jīng)很少使用了。)
初始化的時候,導出類的構造函數(shù)會自動調(diào)用基類的默認構造函數(shù),此過程一直遞歸到最基本的基類。如果需要調(diào)用有參數(shù)的構造函數(shù)就需要手動執(zhí)行。反過來,如果需要進行清理工作(大部分時候我們都不需要),務必手動執(zhí)行基類的清理工作先。比如繼承鏈的每個類都實現(xiàn)dispose()方法,那么執(zhí)行某個類的清理工作的時候,需要手動調(diào)用super.dispose()。不過此種情況下,務必在執(zhí)行super.dispose()之前釋放成員對象,清理順序與執(zhí)行順序是相反的。
此外,構造器方面有更加復雜的調(diào)用機制,我們不用理它,只需要知道一條有效的準則“用盡可能簡單的方法使對象進入正常狀態(tài),如果可以的話避免調(diào)用其它方法”。
java編譯器能夠允許向上多態(tài),就是因為java的機制能保存對象的類型信息,即rtti,正因為這種機制,java編譯器也允許向下轉(zhuǎn)型,以獲得擴展類的“擴展出”的方法。(另,擴展類“擴展”了方法的這種繼承不是“純繼承”,這樣做好不好?用戶自己度量)。向下轉(zhuǎn)型失敗的話會拋出一個classcastexception。
雖然這一章都是在講多態(tài),但是多態(tài)并不總是解決問題最好的方案,它有可能使事情不必要地復雜起來,我們應該總是優(yōu)先考慮更加靈活的組合。
第九章 接口
一種專門提供“接口”的類叫抽象類,若含有至少一個abstract方法,該類就必須被聲明為abstract的。抽象方法沒有方法體,派生類必須實現(xiàn)它,否則派生類也必須被生命為抽象的。
interface關鍵詞使抽象的概念更進了一步:1.這個“類”完全抽象。2.一個類可以向上轉(zhuǎn)型為多種interface。要讓一個類遵循某個特定接口,需要使用implement關鍵字。
在這一章中出現(xiàn)了“策略設計模式”這個詞。創(chuàng)建一個能夠根據(jù)所傳遞的參數(shù)對象的不同而具有不同行為的方法,被稱為策略設計模式。
策略設計模式跟適配器設計模式聯(lián)合使用可以提供非常強大的功能,比如我們遇到了無法更改的類(別人編寫的),想要它滿足我們的接口然后放到設計模式里面去(當然滿足了接口之后的用法就不止如此了),就可以編寫一個適配器,包裝該類同時產(chǎn)生我所需要的接口。