java關鍵字abstract

在java中我們中abstract關鍵字來表達抽象。舉個例子:

我們說車子都可以跑(run)。但有幾個輪子,怎麼跑,對於不同的車有不同的結果。自行車需要人踩着跑,汽車發動機推動跑等等,那麼我們可以車表達爲抽象類。

/**

* 車子類

*/

public abstract class Car {

public abstract void run();

}

/**

* 自行車

*/

class Bicycle extends Car{

@Override

public void run() {

System.out.println("人踩着跑。。。");

}

}

/***

* 汽車

*/

class Automobile extends Car{

@Override

public void run() {

System.out.println("發動機驅動跑。。。");

}

}


假如後面各種車,倒着跑、懸在空中跑隨你怎麼跑,只需要繼承抽象類實現自己的業務就行了。相信大家對java抽象已有一個初步的印象了。

抽象方法:

1、從上面的例子中我們可以看到抽象方法跟普通方法是有區別的,它沒有自己的主體(沒有{}包起來的

業務邏輯),跟接口中的方法有點類似。所以我們沒法直接調用抽象方法

2、抽象方法不能用private修飾,因爲抽象方法必須被子類實現(覆寫),而private權限對於子類來

說是不能訪問的,所以就會產生矛盾

3、抽象方法也不能用static修飾,試想一下,如果用static修飾了,那麼我們可以直接通過類名調

用,而抽象方法壓根就沒有主體,沒有任何業務邏輯,這樣就毫無意義了。

抽象類:

1、用abstract關鍵字來表達的類,其表達形式爲:(public)abstract class 類名{}

2、抽象類不能被實例化,也就是說我們沒法直接new 一個抽象類。抽象類本身就代表了一個類型,無法

確定爲一個具體的對象,所以不能實例化就合乎情理了,只能有它的繼承類實例化。

3、抽象類雖然不能被實例化,但有自己的構造方法(這個後面再討論)

4、抽象類與接口(interface)有很大的不同之處,接口中不能有實例方法去實現業務邏輯,而抽象類

中可以有實例方法,並實現業務邏輯,比如我們可以在抽象類中創建和銷燬一個線程池。

5、抽象類不能使用final關鍵字修飾,因爲final修飾的類是無法被繼承,而對於抽象類來說就是

需要通過繼承去實現抽象方法,這又會產生矛盾。(後面將寫一篇關於finally的文章詳細討論)


抽象類與抽象方法的關聯:

如果一個類中至少有一個抽象方法,那麼這個類一定是抽象類,但反之則不然。也就是說一個抽象類中可

以沒有抽象方法。這樣做的目的是爲了此類不能被實例化。

如果一個類繼承了一個抽象類,那麼它必須全部覆寫抽象類中的抽象方法,當然也可以不全部覆寫,如果

不覆寫全部抽象方法則這個子類也必須是抽象類

public abstract class Car {

public void mothod1(){

}

public abstract void mothod2();

public abstract void method3();

}

class Bicycle extends Car{

@Override

public void mothod2() {//需要覆寫抽象方法mothod2

}

@Override

public void method3() {//需要覆寫抽象方法mothod3

}

}

抽象類的構造器:

先來看一個例子:

public abstract class Car {

Car(){

System.out.println("抽象方法無參構造函數");

}

Car(String a){

System.out.println("抽象有參構造方法");

}

public void mothod1(){

System.out.println(this.getClass());

System.out.println("抽象類的實例方法");

}

public abstract void mothod2();

}

/**

* 自行車

*/

class Bicycle extends Car{

Bicycle(){

System.out.println("子類無參構造函數");

}

@Override

public void mothod2() {//需要覆寫抽象方法mothod2

}

}

/**另一個包的測試類**/

public class Test {

public static void main(String[] args) {

Bicycle b = new Bicycle();

b.mothod1();

}

}

結果:

抽象方法無參構造函數

子類無參構造函數

class com.shaolin.service.impl.Bicycle

抽象類的實例方法


從上面的例子中可以看出:

1、抽象類是有構造方法的(當然如果我們不寫,編譯器會自動默認一個無參構造方法)。而且從結果來看,和普通的繼承類一樣,在new 一個子類對象時會優先調用父類(這裏指的是抽象類Car)的構造器初始化,然後再調用子類的構造器。至此相信大家都會有這樣一個疑問,爲什麼抽象方法不能實例化卻有構造器呢? 對於這個問題網上也中說紛紜,沒有確定答案。

既然它也屬於繼承的範疇,那麼當子類創建對象時必然要優先初始化父類的屬性變量和實例方法,不然子類怎麼繼承和調用呢?而它本身不能實例化,因爲它本身就是不確定的一個對象,如果它能被實例化,那麼我們通過它的對象來調用它本身的抽象方法是不是有問題。所以不能實例化有在情理之中。因此大家只要記住這個規定就行。

2、對於抽象類中的非statci(靜態)和非abstract(抽象)方法中的this關鍵字(靜態方法中不能有關鍵字this之前已經討論過可以參考 關於靜態static那些事)代表的是它的繼承類,而非抽象類本身,這個好理解,因爲抽象類本身不能被實例化。如果有多個繼承類,誰調用this就代表誰。

抽象類有什麼好處呢?

1、由於抽象類不能被實例化,最大的好處就是通過方法的覆蓋來實現多態的屬性。也就是運行期綁定

2、抽象類將事物的共性的東西提取出來,由子類繼承去實現,代碼易擴展、易維護。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章