抽象類和接口的區別

1、抽象類

Interface和抽象類的區別以及什麼狀況下使用抽象類,什麼狀況使用接口:java

1、語法上的區別this

一、接口並非特殊的抽象類,接口沒有構造方法,由於接口中的屬性爲final static修飾,因此不能賦值。一個接口能夠繼承多個接口,而類只能單繼承。spa

二、一個不包括抽象方法的類也能夠定義成抽象類,但沒有意義,抽象方法必定時在抽象類中設計

三、接口中不能有靜態方法或靜態構造快,而抽象方法中能夠有靜態方法或靜態構造塊rest

四、一個類只能繼承一個抽象類,一個類能夠實現多個接口,而且接口能夠繼承多個接口code

2、設計上的區別對象

一、抽象類是一種對事物的抽象,包括了屬性和行爲,而接口是局部的抽象,僅對行爲的抽象。抽象類是對整個類抽象,接口只對類中行爲抽象。 
舉個例子:鳥類和飛機類這兩個不一樣事物的類型,但它們都有一個公共的行爲」飛行」能夠將鳥類定義爲Bird,飛機定義爲Airplane,可是飛行這特性不能定義成類,並非對一類事物的抽象描述,可是能夠給「飛行」設計成接口 Fly fly() ,而後Bird和Airplane根據本身的須要實現該接口。然而不一樣種類的鳥 如:小燕子,老鷹直接繼承Bird類便可具有飛行這特性,對應飛機也相似。 
總結:其實繼承就是一個「是否是的關係」,而接口是」有沒有的關係」,若一個繼承了抽象類,則一定是抽象類的種類,而接口實現時表明有沒有,具不具有的關係。例如鳥類是否能飛(具有飛這特性),若實現了飛行接口,則表明具備飛行特性,不然不具有繼承

二、抽象類做爲多個子類的父類,是一種模板式設計。而接口是一種功能的規範,是一種輻射式設計(也就是當功能規範改變了,那麼實現此規範的類都要改變)。 
例子:模板設計:ppt中的模板,若用模板A設計了ppt B,ppt C。ppt B,和ppt C公共部分就是ppt A。若是它們公共部分須要改動,只須要改動A就好了,不須要從新進行改動。輻射設計:電梯中都安裝了某種報警器,一旦更新該報警器,那麼電梯中都要所有更新。也就是說對於抽象類,若是添加新的方法,能夠直接在抽象類中添加具體的實現,子類不不做改動;而接口不行,若接口改動,則實現該接口的相應類都要改動 
 下面看一個網上流傳最普遍的例子:門和警報的例子:門都有open( )和close( )兩個動做,此時咱們能夠定義經過抽象類和接口來定義這個抽象概念:接口

abstract class Door {
    public abstract void open();
    public abstract void close();
}
  或者:
  
    interface Door {
    public abstract void open();
    public abstract void close();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可是如今若是咱們須要門具備報警alarm( )的功能,那麼該如何實現?下面提供兩種思路: 
  1)將這三個功能都放在抽象類裏面,可是這樣一來全部繼承於這個抽象類的子類都具有了報警功能,可是有的門並不必定具有報警功能; 
  2)將這三個功能都放在接口裏面,須要用到報警功能的類就須要實現這個接口中的open( )和close( ),也許這個類根本就不具有open( )和close( )這兩個功能,好比火災報警器。 
  從這裏能夠看出, Door的open() 、close()和alarm()根本就屬於兩個不一樣範疇內的行爲,open()和close()屬於門自己固有的行爲特性,而alarm()屬於延伸的附加行爲。所以最好的解決辦法是單獨將報警設計爲一個接口,包含alarm()行爲,Door設計爲單獨的一個抽象類,包含open和close兩種行爲。再設計一個報警門繼承Door類和實現Alarm接口。get

  interface Alram {
    void alarm();
}


abstract class Door {
    void open();
    void close();
}

class AlarmDoor extends Door implements Alarm {
    void oepn() {
      //
    }
    void close() {
      //
    }
    void alarm() {
      //
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

何時使用抽象類和接口

一、若是你擁有一些方法而且想讓它們中的一些有默認實現,那麼使用抽象類吧。 
2.若是你想實現多重繼承,那麼你必須使用接口。因爲Java不支持多繼承,子類不可以繼承多個類,但能夠實現多個接口。所以你就可使用接口來解決它。 
3.若是基本功能在不斷改變,那麼就須要使用抽象類。若是不斷改變基本功能而且使用接口,那麼就須要改變全部實現了該接口的類。 
注:使用Java接口和抽象Java類進行變量的類型聲明、參數是類型聲明、方法的返還類型說明,以及數據類型的轉換等。而不要用具體Java類進行變量的類型聲明、參數是類型聲明、方法的返還類型說明,以及數據類型的轉換等

abstract關鍵字

  1. 抽象方法用abstract修飾的而且必定是在抽象類中而且只能是public或protected修飾,可是抽象類中能夠有非抽象方法
  2. 抽象類用abstract修飾的,能夠有屬性,構造方法,也可有實現方法(當該方法是公有時繼承該抽象類的子類可使用)可是不能建立對象(這也證實了建立子類對象不會建立父類對象,若父類爲抽象類時,則建立抽象類的對象,又抽象類不能建立對象,則父類對象不會建立)
  3. 抽象類的方法必定要在非抽象類的子類中重寫,而且在抽象類中必定要提供構造方法(不能將構造方法私有化),由於建立子類對象以前必定要調用父類的構造方法進行對父類屬性初始化,不然子類對象不能夠建立(但不會建立父類對象)

    抽象類和普通類的區別

    1. 抽象方法只能用public、protected修飾(若是用private修飾時,則子類不能繼承抽象類的方法,故不能重寫該方法)默認狀況下是public
    2. 抽象類不能建立對象
    3. 若一個類繼承了抽象類,則必須實現抽象方法,若不實現,則子類也必須爲抽象類 
      模板模式:Template 
      在抽象類中提供抽象方法,該抽象方法推遲到子類中實現

public abstract classs Account { 
private double fund; 
public void setFund(double fund) { 
this.fund = fund; //父類的fund私有屬性怎麼能夠用this訪問,其中this是子類對象的引用,這和私有屬性不能被繼承相矛盾,目前的解釋爲:經過this訪問的fund屬性是在父類中,因此java認爲this能夠訪問父類私有成員,若在子類this.fund時就會編譯出錯,this訪問fund屬性不在父類中 

public double getFund() { 
return fund; 

public double calculateInterest() { 
return getFund()*getInterest(); 

public abstract double getInterest(); 

class AccountA extends Account { 
public double getInterest() { 
retrun 10.0; 


public class Test { 
public static void main(String[]args) 

Account account = new AccountA(); 
double fund = Double.parseDouble(args[0]); 
account.setFund(fund); 
account.calculateInterest(); 

}

interface關鍵字

接口是一種功能規範

  1. 接口中有屬性 併爲 public static final ,因此不能有構造方法進行對屬性初始化(由於屬性是final修飾的,只能聲明式初始化,不能再賦值初始化)
  2. 接口中不能有實現的方法,因此接口是極度抽象的類型,比抽象類還要抽象,通常再也不接口中定義屬性。一個類能夠遵循多個功能規範(接口),一個非抽象類遵循了某個接口,則就要實現該接口中全部的方法,對應抽象類遵循此接口時,能夠不實現該接口中的方法,等到子類來實現其接口的方法
  3. 一個接口能夠繼承多個接口(能夠說明接口不是類)而一個類只能繼承一個類
  4. 接口的類型指向實現的接口對象 叫接口回調不是上轉型,而父類引用指向子類對象叫上轉型
相關文章
相關標籤/搜索