1. 程式人生 > >探究Java的介面和抽象類--------Java的系列學習之路(12)

探究Java的介面和抽象類--------Java的系列學習之路(12)

前言——

今天第二天軍訓,訓得有點累,但是訓完整個人感覺很舒服,之前太久沒運動讓整個人感覺起來都很沒有 活力~   注:歡迎轉載,轉載請註明來處

目錄

一.抽象類

一.抽象類

a.要了解抽象類之前,我們需要先知道什麼是抽象方法?

抽象方法就是方法前面加上abstract修飾,且類中的抽象方法只有宣告,沒有實現。

b.知道了什麼是抽象方法之後,那抽象類是什麼呢?

含有抽象方法的類稱為抽象類,如果一個類含有抽象方法,那麼我們必須在這個類的簽名加上abstract關鍵字來把它宣告為抽象類,不然就會像下面這樣報錯。

在第14行中聲明瞭一個抽象方法,那麼Car就是一個抽象類了,但是忘了加abstract了,因此報錯了。

正確如下:
abstract class Car{
	
     abstract public void airCondition() ;
}

c.抽象類的存在有何意義?

抽象類純粹是為了繼承而生的。如果一個方法在父類中實現出來沒有任何意義的話,必須根據子類的實際情況來進行對應的實現,那麼我們就可以把該方法宣告為抽象方法,進而再把該類宣告為抽象類。如果定義了一個抽象類,但是卻沒有任何子類繼承它的話,那麼可以說這個抽象類就廢了。。

d.關於抽象類和非抽象類的一些區別

1)抽象方法在抽象類中只能是public(隱式指定為public)或者protected屬性的,不能為private,不然會報錯。

其實這個也是非常容易理解的,因為private方法無法被繼承。

2)抽象類不能用來建立一個物件,說白了也就是不能new。

3)如果子類只對抽象父類中的部分抽象方法進行自我實現的話,那麼這個子類也還是算抽象類,必須將這個子類加上abstract來定義成抽象類。只有對抽象父類的全部抽象方法進行自我實現,那麼才能把這個子類定義為非抽象類。

在這邊,子類bus沒有把抽象父類Car中的skyLight()方法進行自我實現,所以繼承完之後,bus中還是有抽象方法,所以bus類理所應當還是abstract類,所以應該在24行前面加上一個abstract。

除以上3點外,抽象類和其他類沒有任何其他差別。

二.介面(interface)

介面在軟體開發中,泛指供別人呼叫的方法或者函式。在Java中是對一類行為的抽象(下面會對此句話進行解釋,方便大家理解)

1.介面中的細節。

介面中可以定義方法或者變數。介面中的變數會被隱式指定為 public static final,但是介面中一般不定義變數。介面中的方法都會被隱式指定為public abstract,都是公共的抽象方法(只能為public,設定為private或者protected會報錯)。

2.類呼叫介面的語法結構

class  xxxx implements  interface1,interface2...{

}

可以看到,允許一個類呼叫多個介面,但是要注意,只有把所呼叫介面中的每個抽象方法都自我實現後,才能把這個子類宣告為非抽象類;如果沒有把介面中的抽象方法全部自我實現的話,那麼這個類由於仍然含有抽象方法,所以仍然是抽象類。因此要把這個類宣告為abstract 類,不然會報錯。如下面所示,Bus沒有把skyLight這個介面中的showSkyLight()進行自我實現,這時候就應該在21行前面新增一個abstract,宣告為抽象 類。

三.抽象類和介面的比較

1)一個子類只能繼承一個抽象類(Java中的單繼承),但是一個子類可以繼承多個interface,一定程度上來講,Java中的介面就是為了彌補無法多繼承帶來的不方便。

2)抽象類中可以有抽象方法,也可以有非抽象方法,但是介面中只能有public abstract的抽象方法。同理,抽象類中的變數可以是多種型別的,但是介面中的變數就只能是public static final型別的。

3)設計層面上的不同,這塊我會具體展開

假如我要建立一個bus物件和一個貨車物件,由於貨車和bus的汽車都屬於汽車,那麼我自然會建立一個Car類,這個Car類含有汽車的共同屬性,比如都含有前進,後退,左轉,右轉,空調,加速,減速等。但是在Car類中沒有必要對這麼多的共同屬性進行定義,一部分只需要子類繼承時再自我實現就可以了。所以啊,把一些方法設定為抽象方法,再把Car類設定為抽象類,這無疑是最好的選擇。

建立一個抽象Car類之後,假如bus需要含有無人駕駛的功能,那麼我們應該如何把無人駕駛這個屬性或者方法新增進去呢?一個很自然的想法就是在bus內部自己新增一個無人駕駛的方法。但是這樣設計我覺得不大好啊,無人駕駛的功能可能存在多種子類上,比如無人駕駛的小車,公交車,甚至貨車,如果分別在其內部加入同一個功能的話,那麼感覺有點重複。

另一個想法,就是在抽象類中新增一個抽象的無人駕駛的對應方法,這樣一來,繼承它的子類就都具有無人駕駛的方法了,但是這樣也是不行啊,有的子類沒有無人駕駛的功能,那麼它就不會自己去實現無人駕駛這個方法的定義,那麼這時子類就還是抽象類了,不能建立物件了,這不符合我們的需要啊,我們需要建立子類物件。

最好的方法就是建立一個interface,這個介面含有抽象的無人駕駛方法,有需要的拓展無人駕駛這個功能的子類只需自行遵循這個介面就可以啦!!

說到這邊,大家是不是有點感覺了,抽象類中的方法偏向於一些很基本的屬性方法,比如Car都一定要有的加速和剎車功能。而interface中的抽象方法是一些拓展屬性,需要的可以自行遵循介面,如無人駕駛功能

所以最好的設計如下: