1. 程式人生 > >Java編程思想(七、復用類)

Java編程思想(七、復用類)

ces java編程 語法 現在 運行 加載 沒有 調用 實例變量

   復用代碼是Java眾多引人註目的功能之一。

   復用類有兩個方法。第一種:只需在新的類中產生現有類的對象。由於新的類是由現有類的對象所組成,所以這種方法稱為組合。第二種:按照現有類的類型來創建新類。無需改變現有類的形式,采用現在類的形式並在其中添加新代碼。這種方式稱為繼承。

   1、組合語法。只需將對象引用置於新類中即可。編譯器並不會簡單地偉每一個引用都創建默認對象。如果想要初始化這些引用,可以在代碼中的下列位置進行:1)、在定義對象的地方。這意味著它們總是能夠在構造器被調用之前被初始化。2)、在類的構造器中 3)、就在正要使用這些對象之前,這種方式稱為惰性初始化。判一次空,如果為空則初始化。4)、使用實例初始化。

   2、繼承語法。當創建一個類時,總是在繼承。Java中所有的類都來自於根類Object。在繼承過程中,需要先聲明“新類與舊類相似”。這種聲明是通過在類主體的左邊花括號之前,書寫後面緊隨基類名稱的關鍵字extends而實現的。當這麽做時,會自動得到基類中所有的域和方法。

    1)、初始化基類。繼承並不只是復制基類的接口。當創建了一個導出類的對象時,該對象包含了一個基類的子對象。這個子對象與你用基類直接創建的對象是一樣的。二者區別在於,後者來自外部,而基類的子對象被包裝在導出類對象內部。

    2)、帶參數的構造器。如果沒有構造器,或者想調用一個帶參數的基類構造器,就必須用關鍵字super顯式地編寫基類構造器的語句。

   3、代理。Java並沒有直接提供對它的支持。用代碼介紹比較容易理解。

public class SpaceShipDelegation{
     private SpaceShipControls controls = new SpaceShipControls();
     public void back(int velocity){
       controls.back(velocity);          
  }          
}

和組合類似,但是比組合多包裝了一層。這樣可以控制,controls暴露哪些方法。如果是組合,那麽controls中的所有方法都會暴露出來。

  4、確保正確清理。許多情況下,清理並不是問題,僅需讓垃圾回收器完成該動作就行。但當必須親自處理清理時,就要多加小心。因為,垃圾回收器可能永遠也無法被調用,即時被調用,它是按照任何它想要的順序來回收對象。最好的辦法是除了內存以外,不能依賴垃圾回收器去做任何事。如果需要清理,就自己寫一個清理方法,但不要使用finalize()。

public static void main(String[] args){
  CADSystem  x = new CADSystem ();  
   try{
   } finally{
     x.dispose();   //try塊退出時,一定會調用finally子句。
  }          
}    

  5、名稱屏蔽。如果Java的基類已經擁有某個已被多次重載的方法名稱(參數列表不同)。那麽在導出類中重新定義該方法名稱並不會屏蔽其在基類中的任何版本。因此,無論是在該層或者它的基類中隊方法進行定義,重載機制都可以正常工作。

    Java SE5中增加了@Override註解。它並不是關鍵字,但是可以把它當作關鍵字使用。當你選擇覆寫某個方法時,可以選擇添加這個註解。

  6、在組合與繼承之間選擇。組合和繼承都允許在新的類中放置子對象,組合是顯式地這樣做,而繼承是隱式地做。一般來說很簡單。如果是“is-a”的關系,那就使用繼承。如果是“has-a”的關系,那就使用組合。

  7、protected關鍵字。在實際項目中,經常會想要將某些事物盡可能8、對這個世界隱藏起來,但仍允許導出類的成員訪問它們。這時候便可以使用protected關鍵字。

  8、向上轉型。派生類引用向上轉型成為基類引用。因為派生類一定具有基類的方法。所以這種轉型是肯定可以的。類接口唯一可能發生的事情是丟失方法,而不是獲取它們。

  9、final關鍵字。下面介紹一下final的三個使用場景:數據,方法和類。

    1)、final數據。一:一個永遠不變的編譯時常量。 二:一個在運行時被初始化的值,但不會再被改變。這是針對於基本數據類型。如果當final修飾一個引用的時候,那是意味著這個引用永遠不能再改變了,不能再指向其他對象,但是對象的內容是可以改變的。

    2)、空白final。所謂空白final指被聲明為final但又未給定初值的域。但編譯器必須確保空白final在使用前必須被初始化。所以必須在域的定義處或者每個構造器中用表達式對final進行賦值。

    3)、final參數。Java允許在參數列表中以聲明的方式將參數指明為final。這意味著你無法在方法中更改參數引用所指向的對象。

    4)、final方法。使用final方法有兩個原因。1、把方法鎖定,以防任何繼承類修改它的含義。可以確保在繼承中使方法行為保持不變,並且不會被覆蓋。2、是使用final方法時。等於同意編譯器將針對這個方法的所有調用轉為內嵌調用。但現在一般只有要明確靜止覆蓋時,才將方法設置為final。

    5)、final和private關鍵字。類中的所有private方法都隱式地指定為是final。由於無法取用private方法,所以也就無法覆蓋它。對private方法添加final修飾詞是沒有什麽意義的。

    6)、final類。當將某個類的整體定義為final時(通過關鍵字final置於它的定義之前),就表明了你不打算繼承該類,並且也不允許別人這麽做。

  10、初始化及類的加載。Java中的所有事物都是對象。所以它采用了不同的加載方式。每個類的編譯代碼都在它自己的獨立的文件之中,該文件只有需要使用程序代碼時才會被加載。“類的代碼在初次使用時才加載”。這通常是指加載發生在創建類的第一個對象之時,但是當訪問static域或static方法時,也 發生加載。其實構造器也是static方法,盡管static關鍵字並沒有顯式地寫出來。因此更準確地講,類是在其任何static成員被訪問時加載的。

    運行一個類時的加載順序是這樣的:假設該類名為Bettle。首先訪問Beetle.main()(一個static方法),於是加載器開始啟動並找出Beetle類的編譯代碼(在名為Beetle.class的文件之中)。在對它進行加載的過程中,編譯器註意到它有一個基類(這是由關鍵字extends得知的),於是它繼續進行加載。不管你是否打算產生一個該基類的對象,這都要發生。如果該基類還有其自身的基類,那麽第二個基類就會被加載,如此類推。接下來,根基類中的static初始化即會被執行,然後是下一個導出類,以此類推。這種方式很重要,因為導出類的static初始化可能會依賴於基類成員能否被正確初始化。至此,必要的類都有已經加載完畢。於是就可以開始創建對象。首先,對象中所有的基本類型都會被設為默認值,對象引用被設為null--這是通過將對象的內存設為二進制靈零值而一舉產生的。然後,基類的構造器會被調用。在本例中,它是被自動調用的。但也可以用super來指定對基類構造器的調用。基類構造器和導出類的構造器一樣,以相同的順序來經歷相同的過程。在基類構造器完成之後,實例變量按其次序被初始化。最後,構造器的其余部分被執行。

Java編程思想(七、復用類)