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(); }
可是如今若是咱們須要門具備報警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() { // }
何時使用抽象類和接口
一、若是你擁有一些方法而且想讓它們中的一些有默認實現,那麼使用抽象類吧。
2.若是你想實現多重繼承,那麼你必須使用接口。因爲Java不支持多繼承,子類不可以繼承多個類,但能夠實現多個接口。所以你就可使用接口來解決它。
3.若是基本功能在不斷改變,那麼就須要使用抽象類。若是不斷改變基本功能而且使用接口,那麼就須要改變全部實現了該接口的類。
注:使用Java接口和抽象Java類進行變量的類型聲明、參數是類型聲明、方法的返還類型說明,以及數據類型的轉換等。而不要用具體Java類進行變量的類型聲明、參數是類型聲明、方法的返還類型說明,以及數據類型的轉換等
abstract關鍵字
抽象類的方法必定要在非抽象類的子類中重寫,而且在抽象類中必定要提供構造方法(不能將構造方法私有化),由於建立子類對象以前必定要調用父類的構造方法進行對父類屬性初始化,不然子類對象不能夠建立(但不會建立父類對象)
抽象類和普通類的區別
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關鍵字
接口是一種功能規範