Java的介面和抽象類別以及兩者之間的區別

來源:互聯網
上載者:User

對於物件導向編程來說,抽象是它的一大特徵之一。在Java中,可以通過兩種形式來體現OOP的抽象:介面和抽象類別。這兩者有太多相似的地方,又有太多不同的地方。很多人在初學的時候會以為它們可以隨意互換使用,但是實際則不然。今天我們就一起來學習一下Java中的介面和抽象類別。下面是本文的目錄大綱:

一.抽象類別

二.介面

三.抽象類別和介面的區別

若有不正之處,請多多諒解並歡迎批評指正,不甚感激。

一.抽象類別

在瞭解抽象類別之前,先來瞭解一下抽象方法。抽象方法是一種特殊的方法:它只有聲明,而沒有具體的實現。抽象方法的聲明格式為:

abstract void fun();

抽象方法必須用abstract關鍵字進行修飾。如果一個類含有抽象方法,則稱這個類為抽象類別,抽象類別必須在類前用abstract關鍵字修飾。因為抽象類別中含有無具體實現的方法,所以不能用抽象類別建立對象。

  下面要注意一個問題:在《Java編程思想》一書中,將抽象類別定義為“包含抽象方法的類”,但是後面發現如果一個類不包含抽象方法,只是用abstract修飾的話也是抽象類別。也就是說抽象類別不一定必須含有抽象方法。個人覺得這個屬於鑽牛角尖的問題吧,因為如果一個抽象類別不包含任何抽象方法,為何還要設計為抽象類別?所以暫且記住這個概念吧,不必去深究為什麼。

 
  1. [public] abstract class ClassName {

  2. abstract void fun();

  3. }

從這裡可以看出,抽象類別就是為了繼承而存在的,如果你定義了一個抽象類別,卻不去繼承它,那麼等於白白建立了這個抽象類別,因為你不能用它來做任何事情。對於一個父類,如果它的某個方法在父類中實現出來沒有任何意義,必鬚根據子類的實際需求來進行不同的實現,那麼就可以將這個方法聲明為abstract方法,此時這個類也就成為abstract類了。

包含抽象方法的類稱為抽象類別,但並不意味著抽象類別中只能有抽象方法,它和普通類一樣,同樣可以擁有成員變數和普通的成員方法。注意,抽象類別和普通類的主要有三點區別:

1)抽象方法必須為public或者protected(因為如果為private,則不能被子類繼承,子類便無法實現該方法),預設情況下預設為public。

2)抽象類別不能用來建立對象;

3)如果一個類繼承於一個抽象類別,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義為為abstract類。

在其他方面,抽象類別和普通的類並沒有區別。

二.介面

介面,英文稱作interface,在軟體工程中,介面泛指供別人調用的方法或者函數。從這裡,我們可以體會到Java語言設計者的初衷,它是對行為的抽象。在Java中,定一個介面的形式如下:

 
  1. [public] interface InterfaceName {

  2. }

介面中可以含有 變數和方法。但是要注意,介面中的變數會被隱式地指定為public static final變數(並且只能是public static final變數,用private修飾會報編譯錯誤),而方法會被隱式地指定為public abstract方法且只能是public abstract方法(用其他關鍵字,比如private、protected、static、 final等修飾會報編譯錯誤),並且介面中所有的方法不能有具體的實現,也就是說,介面中的方法必須都是抽象方法。從這裡可以隱約看出介面和抽象類別的區別,介面是一種極度抽象的類型,它比抽象類別更加“抽象”,並且一般情況下不在介面中定義變數。

要讓一個類遵循某組特地的介面需要使用implements關鍵字,具體格式如下:

 
  1. class ClassName implements Interface1,Interface2,[....]{

  2. }

可以看出,允許一個類遵循多個特定的介面。如果一個非抽象類別遵循了某個介面,就必須實現該介面中的所有方法。對於遵循某個介面的抽象類別,可以不實現該介面中的抽象方法。

三.抽象類別和介面的區別

1.文法層面上的區別

1)抽象類別可以提供成員方法的實現細節,而介面中只能存在public abstract 方法;

2)抽象類別中的成員變數可以是各種類型的,而介面中的成員變數只能是public static final類型的;

3)介面中不能含有靜態代碼塊以及靜態方法,而抽象類別可以有靜態代碼塊和靜態方法;

4)一個類只能繼承一個抽象類別,而一個類卻可以實現多個介面。

2.設計層面上的區別

1)抽象類別是對一種事物的抽象,即對類抽象,而介面是對行為的抽象。抽象類別是對整個類整體進行抽象,包括屬性、行為,但是介面卻是對類局部(行為)進行抽象。舉個簡單的例子,飛機和鳥是不同類的事物,但是它們都有一個共性,就是都會飛。那麼在設計的時候,可以將飛機設計為一個類Airplane,將鳥設計為一個類Bird,但是不能將 飛行 這個特性也設計為類,因此它只是一個行為特性,並不是對一類事物的抽象描述。此時可以將 飛行 設計為一個介面Fly,包含方法fly( ),然後Airplane和Bird分別根據自己的需要實現Fly這個介面。然後至於有不同種類的飛機,比如戰鬥機、民用飛機等直接繼承Airplane即可,對於鳥也是類似的,不同種類的鳥直接繼承Bird類即可。從這裡可以看出,繼承是一個 “是不是”的關係,而 介面 實現則是 “有沒有”的關係。如果一個類繼承了某個抽象類別,則子類必定是抽象類別的種類,而介面實現則是有沒有、具備不具備的關係,比如鳥是否能飛(或者是否具備飛行這個特點),能飛行則可以實現這個介面,不能飛行就不實現這個介面。

2)設計層面不同,抽象類別作為很多子類的父類,它是一種模板式設計。而介面是一種行為規範,它是一種輻射式設計。什麼是模板式設計?最簡單例子,大家都用過ppt裡面的模板,如果用模板A設計了ppt B和ppt C,ppt B和ppt C公用的部分就是模板A了,如果它們的公用部分需要改動,則只需要改動模板A就可以了,不需要重新對ppt B和ppt C進行改動。而輻射式設計,比如某個電梯都裝了某種通報器,一旦要更新通報器,就必須全部更新。也就是說對於抽象類別,如果需要添加新的方法,可以直接在抽象類別中添加具體的實現,子類可以不進行變更;而對於介面則不行,如果介面進行了變更,則所有實現這個介面的類都必須進行相應的改動。

下面看一個網上流傳最廣泛的例子:門和警報的例子:門都有open( )和close( )兩個動作,此時我們可以定義通過抽象類別和介面來定義這個抽象概念:

 
  1. abstract class Door {

  2. public abstract void open();

    public abstract void close();

  3. }

或者:

 
  1. interface Door {

  2. public abstract void open();

  3. public abstract void close();

    }

但是現在如果我們需要門具有警示alarm( )的功能,那麼該如何??下面提供兩種思路:

1)將這三個功能都放在抽象類別裡面,但是這樣一來所有繼承於這個抽象類別的子類都具備了警示功能,但是有的門並不一定具備警示功能;

2)將這三個功能都放在介面裡面,需要用到警示功能的類就需要實現這個介面中的open( )和close( ),也許這個類根本就不具備open( )和close( )這兩個功能,比如火災通報器。

從這裡可以看出, Door的open() 、close()和alarm()根本就屬於兩個不同範疇內的行為,open()和close()屬於門本身固有的行為特性,而alarm()屬於延伸的附加行為。因此最好的解決辦法是單獨將警示設計為一個介面,包含alarm()行為,Door設計為單獨的一個抽象類別,包含open和close兩種行為。再設計一個警示門繼承Door類和實現Alarm介面。


 
  1. interface Alram {

  2. void alarm();

  3. }


  4. abstract class Door {

  5. void open();

  6. void close();

  7. }

    class AlarmDoor extends Door implements Alarm {


  8. void oepn() {

  9. //....

  10. }

  11. void close() {

  12. //....

  13. }

  14. void alarm() {

  15. //....

  16. }

  17. }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.