天天看點

JAVA---類再生

複用代碼是Java衆多引人注目的功能之一。但要想成為極具革命性的語言,僅僅能夠複制代碼并對之加以改變是不夠的,它還必須能夠做更多的事情。

兩種代碼重用機制:組合和繼承

1.組合文法

 組合:将對象引用置于新類中

 類中域為基本變量時能夠自動被初始化為零。但是對象引用會被初始化為null

 初始化引用,可以在代碼中下列位置進行:

  1.在定義對象的地方。這意味着它們總是能夠在構造器之前被初始化

  2.在類的構造器中

  3.就在正要使用這些對象之前,這種方式稱為惰性初始化

  4.使用執行個體初始化。

2.繼承文法

 繼承是所有OOP語言和Java語言不可缺少的部分。當建立一個類時,總是在繼承,因為,除非已明确指出要從其他類中繼承,

 否則就是在隐式地從Java的标準根類Object進行繼承。

 class A extends B{}

 2.1初始化基礎類

 使用super 關鍵字

3.組合與繼承的結合

 許多時候都要求将合成與繼承兩種技術結合起來使用。

 3.1 確定正确的清除

  垃圾收集器會在必要的時候自動回收記憶體。垃圾收集器大多數時候都能很好地工作,但在某些情況下,我們的類可能在自己的存在時期采取一些行動,

 而這些行動要求必須進行明确的清除工作。

  垃圾收集的順序:不能指望自己能确切知道何時會開始垃圾收集。垃圾收集器可能永遠不會得到調用。即使得到調用,它也可能以自己願意的任何順序回收對象。

 除此以外,Java 1.0 實作的垃圾收集器機制通常不會調用finalize()方法。除記憶體的回收以外,其他任何東西都最好不要依賴垃圾收集器進行回收。

 若想明确地清除什麼,請制作自己的清除方法,而且不要依賴finalize()。然而正如以前指出的那樣,可強迫Java1.1 調用所有收尾子產品(Finalizer)。

4.再論合成與繼承

  在面向對象的程式設計中,建立和使用代碼最可能采取的一種做法是:将資料和方法統一封裝到一個類裡,并且使用那個類的對象。有些時候,

 需通過“合成”技術用現成的類來構造新類。而繼承是最少見的一種做法。是以,盡管繼承在學習OOP 的過程中得到了大量的強調,但并不意味着應該盡可能地到處使用它。

 相反,使用它時要特别慎重。隻有在清楚知道繼承在所有方法中最有效的前提下,才可考慮它。為判斷自己到底應該選用合成還是繼承,一個最簡單的辦法就是考慮是否

 需要從新類上溯造型回基礎類。若必須上溯,就需要繼承。但如果不需要上溯造型,就應提醒自己防止繼承的濫用。 

5.protected

 意思是“它本身是私有的,但可由從這個類繼承的任何東西或者同一個包内的其他任何東西通路”。也就是說,Java 中的protected 會成為進入“友好”狀态。

6.累積開發

  繼承的一個好處是它支援“累積開發”,允許我們引入新的代碼,同時不會為現有代碼造成錯誤。這樣可将新錯誤隔離到新代碼裡。通過從一個現成的、功能性的類繼承,

 同時增添成員新的資料成員及方法(并重新定義現有方法),我們可保持現有代碼原封不動(另外有人也許仍在使用它),不會為其引入自己的程式設計錯誤。一旦出現錯誤,

 就知道它肯定是由于自己的新代碼造成的。這樣一來,與修改現有代碼的主體相比,改正錯誤所需的時間和精力就可以少很多。

7.上溯造型

 繼承最值得注意的地方就是它沒有為新類提供方法。繼承是對新類和基礎類之間的關系的一種表達。可這樣總結該關系:“新類屬于現有類的一種類型”。

 何謂“上溯造型”?之是以叫作這個名字,除了有一定的曆史原因外,也是由于在傳統意義上,類繼承圖的畫法是根位于最頂部,再逐漸向下擴充。

8.final 關鍵字 

 意思就是聲明“這個東西不能改變”。之是以要禁止改變,可能是考慮到兩方面的因素:設計或效率。我們将讨論final 關鍵字的三種應用場合:資料、方法以及類。

 8.1 final資料

 許多程式設計語言都有自己的辦法告訴編譯器某個資料是“常數”。常數主要應用于下述兩個方面:

  (1) 編譯期常數,它永遠不會改變

  (2) 在運作期初始化的一個值,我們不希望它發生變化

 對于基本資料類型,final 會将值變成一個常數;但對于對象句柄,final 會将句柄變成一個常數。進行聲明時,必須将句柄

初始化到一個具體的對象。而且永遠不能将句柄變成指向另一個對象。然而,對象本身是可以修改的

  空白final:它們屬于一些特殊的字段。盡管被聲明成final,但卻未得到一個初始值。無論在哪種情況下,空白final 都必須在實際使用前得到正确的初始化。

 而且編譯器會主動保證這一規定得以貫徹。然而,對于final 關鍵字的各種應用,空白final 具有最大的靈活性。現在強行要求我們對final 進行指派處理——

 要麼在定義字段時使用一個表達 式,要麼在每個建構器中。這樣就可以確定final 字段在使用前獲得正确的初始化。

  final 自變量:Java 1.1 允許我們将自變量設成final 屬性,方法是在自變量清單中對它們進行适當的聲明。這意味着在一個方法的内部,我們不能改變自變量

 句柄指向的東西。

 8.2 final方法

  之是以要使用final 方法,可能是出于對兩方面理由的考慮。第一個是為方法“上鎖”,防止任何繼承類改變它的本來含義。設計程式時,若希望一個方法的行為

 在繼承期間保持不變,而且不可被覆寫或改寫,就可以采取這種做法。采用final 方法的第二個理由是程式執行的效率.

 8.3 final類

  如果說整個類都是final(在它的定義前冠以final 關鍵字),就表明自己不希望從這個類繼承,或者不允許其他任何人采取這種操作。

9.初始化和類裝載

  在許多傳統語言裡,程式都是作為啟動過程的一部分一次性載入的。随後進行的是初始化,再是正式執行程式。在這些語言中,必須對初始化過程進行慎重的控制,

 保證static 資料的初始化不會帶來麻煩。比如在一個static 資料獲得初始化之前,就有另一個static 資料希望它是一個有效值,那麼在C++中就會造成問題。

 Java 則沒有這樣的問題,因為它采用了不同的裝載方法。由于Java 中的一切東西都是對象,,每個對象的代碼都存在于獨立的檔案中。除非真的需要代碼,

 否則那個檔案是不會載入的。