java中抽象類和接口之間的區別和關係

首先抽象類歸根結底還是屬於類,對於抽象方法,是隻能存在於抽象類中的,我們無法再一個非抽象的類中聲明一個抽象方法,其次抽象方法只需要聲明,並不需要事先。當我們要寫一個抽象類的時候只需要在類的前面聲明爲abstract即可了。同時抽象類是無法被實例化的,而抽象類的存在就是爲了被繼承的,在我們定義類的時候,有的時候需要定義一個這樣的抽象類但是不想將其進行實例化的時候就可以定義一個抽象類,比如我們想要定義一些動物的類,這些動物包含很多不同種的動物,但是我們也的確沒有必要實例化一個總的動物的對象,因爲並不存在這樣的對象。我們值得注意的是,對於抽象類,有以下三點值得我們注意:

  1、抽象類中的抽象方法必須定義爲protected或者public,因爲如果我們將其定義爲私有的話,就無法被子類繼承(其實也不是不好繼承,而是不好調用)

  2、抽象類中的抽象方法如果沒有在某一個子類中實現(也就是該子類直接繼承了這個父類而沒有重寫該抽象方法),該子類也必須定義爲抽象類

  3、抽象類是不可以實例化的。

  在其他方面,抽象類並沒有表現出和普通的類的不同。

[public] abstract class MyClass{
	abstract int fun();
}

  我們可以看的到,抽象類的誕生就是爲了繼承的。

  然後我們再來看接口(interface),首先接口是一種完完全全抽象的類(當然也有人說接口並不是類,不過這不重要),接口是爲方法而生的,是作爲一種方法的抽象存在的,接口中可以有變量和方法,但是接口中的變量是被強制置爲public static final 的,並且只能爲該類型,一旦用private來修飾就會報出錯誤。對於接口中的方法,能且只能是public abstract方法,而且對於接口中的方法都不能有具體實現(實際上抽象方法都是這樣的)。在這裏我們也可以看得出來接口和類之間的巨大區別,接口看上去更加純粹的抽象。接口以關鍵詞interface來修飾。

[public] interface InterfaceName {
 
}//這是一個空的接口
  接口解決了一個非常重要的問題,就是多重繼承的問題,我們定義了一個類,它肯定是不可以繼承自多個類的(這個很容易理解,因爲如果這兩個類有相同名字和參數表返回值的方法,對於同時繼承了這兩個類的子類在調用相應方法的時候,最終調用哪一個就成了一個讓人頭疼的問題),但是接口不一樣,我們定義的任何一個類是可以實現多個接口的,同時對於一個接口在不同的類中也可以有不同的實現.

  下面我們簡單分析一下接口和抽象類在各個方面不同的區別:

  在語法方面:

  1、在抽象類中的方法是可以有具體的實現的,只是對於這個類而言不存在實例化這個過程,而在接口中的方法只能是public abstract的;

  2、在抽象類中的變量是可以有多種的,但是在接口中只能是public abstract final的

  3、接口中是不能含有靜態代碼塊或者靜態方法,但是抽象類中是可以有靜態代碼塊和靜態方法

  4、一個類只能繼承一個抽象類,但是一個類可以實現多個接口

  同時,在定義和設計的方面:

  抽象類歸根結底還是更像類一些,也就是說實際上還是對現實事物的描述,而接口則是一種對行爲的抽象。

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

abstract class Door {
    public abstract void open();
    public abstract void close();
}
或者

interface Door {
    public abstract void open();
    public abstract void close();
}

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

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

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

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

interface Alram {
    void alarm();
}
 
abstract class Door {
    void open();
    void close();
}
 
class AlarmDoor extends Door implements Alarm {
    void oepn() {
      //....
    }
    void close() {
      //....
    }
    void alarm() {
      //....
    }
}





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