1. 程式人生 > >java基礎複習---組合、繼承、代理(部分)--11.7

java基礎複習---組合、繼承、代理(部分)--11.7

要想複用程式碼,java中有兩種方式。一種只需在新類中產生現有類的物件。由於新的類是由現有類的物件組成,所以這種方法稱為組合;另一種方式按照現有類的型別來建立新類,無需改變現有類的形式,採用現有類的形式在其中新增新程式碼,這種方式稱為繼承。

一、組合

假設需要某個物件,它具有很多String物件,幾個基本資料型別,以及另一個類的物件。對於非基本型別的物件,必須將其引用至於新的類中,但可以直接定義基本資料型別。

從上面輸出中可以看到source輸出了s的值,這是因為"source =" + source , 需要一個String物件,編譯器則會呼叫WaterSource的toString方法轉換為String。或許你會覺得呼叫toString方法作為一個字串都知道,但是你怎麼說明組合呢?來試一下下一個例子。

在這裡,Teacher類和Student類都有成員變數People使得我們可以使用People類中的方法,通過呼叫people 的life方法來說明了,老師和學生也是人。並且還有自己獨特的任務和學習。我是第一次聽到組合的概念,之前學習到過繼承,發現,和繼承差不多的功能啊,為什麼不直接使用繼承呢?先來複習下繼承,然後區別下兩者的不同。

二、繼承

繼承是java語言中不可缺少的組成部分。當建立一個類時,總是在繼承,因此除非明確指出了繼承了哪個類,否則就是隱式地從Object類中進行繼承。而要指明是繼承了哪個類,是使用extends關鍵字實現的。先來看書上的例子吧

為什麼要先看書上的例子呢?因為發現了一個盲點,首先呢是main方法的呼叫,可以在另一個類中的main方法中呼叫另一個類的main方法,這個是我之前沒有用過的。還有這裡Cleanser類中的方法都是public修飾的,如果不加修飾詞,預設是包訪問許可權,它允許同包內的成員訪問。而繼承的規則呢,就是將所有的資料成員指定為private,將所有的方法指定為public,如果有特殊需求需要做出調整。繼承,不顯示的展現出父類的方法,也可以呼叫。現在用繼承來實現以下組合中使用的例子吧。

對比組合的程式碼,少了許多,輸出結果也相同。那到底使用如何選擇使用呢?再瞭解更多後會做出解釋,繼續看吧。

三、初始化父類(書上是基類,也就是被繼承的類)

對於這塊的內容,我的理解就是,新建子類物件時,會初始化父類,也就是呼叫了父類的構造器。分不同情景來看一下

可以從結果中看到,先訪問了Art的構造器,再訪問了Drawing的構造器,最後才訪問了Reuse4的構造器。也就是說,在呼叫子類的構造器之前,總會呼叫父類的構造器。

可以看到,在這裡,即使Face沒有無參構造,也訪問了父類的構造器。並且進行了初始化成員變數n。從之前的筆記裡說道,一個類的載入,會先初始化成員變數再呼叫構造器,這裡說明了載入這個類之前,先去載入了它的父類構造器。來試一下吧。

通過執行結果,可以得出當例項化一個子類物件時,先去載入它的父類,然後才會載入本類。

上面的例子中,我們都使用的是無參構造器,如果沒有無參構造的父類,或者說我們需要呼叫一個帶引數的父類構造器,怎麼做呢?使用super關鍵字顯示的去呼叫父類構造器的語句。

那當我們不去寫super(i)呢?

就會提示我們新增,如果我們沒有在子類提供一個有參構造呢?

報錯了,來看下報錯語句

嗯,可能有些模糊,大概意思呢,就是父類沒有無參構造,你必須提供一個,或者

點選紅色線條,按提示處理,是寫出了一個有參構造,並呼叫了super(i)。

對於初始化父類的情況呢,就是這些了。

四、代理

代理呢,就是既要講一個成員物件置於所要構造的類中(組合),與此同時,也在新類中暴露了該成員物件的所有方法(繼承)。比如要造一個太空船,太空船需要一個控制模組

使用繼承方式構造一個太空船

但是這裡SpaceShip並不是真正的SpaceShipControls型別,而是包含了SpaceShipControls,並且SpaceShipControls中的所有方法都暴露了出來,而代理就解決了這個問題。

可以看到,對於上面的方法如何傳遞給controls的,而其介面也就與使用繼承得到的介面相同了,但是代理多了更多的控制,因為我們可以選擇只提供成員物件方法的某個子集。