2009-08-03 122 views
26

爲什麼創建抽象類或接口類,或者我們應該在什麼時候使用抽象類或接口類?何時使用抽象類或接口?

+1

[Java抽象類和接口]的可能重複(http://stackoverflow.com/questions/5094825/java-abstract-class-and-interface) – duffymo 2011-06-06 12:23:37

+1

http://stackoverflow.com/questions/761194/interface -vs-abstract-class-general-oo – 2011-11-11 22:40:03

+0

https://stackoverflow.com/questions/479142/when-to-use-an-interface-instead-of-an-abstract-class-and-vice-versa contains best答案 – 2017-10-19 07:04:44

回答

37

當您只想聲明類必須擁有哪些方法和成員時,使用接口。任何實現該接口的人都必須聲明和實現接口列出的方法。

如果您還想要默認實現,請使用抽象類。任何擴展抽象類的類都必須實現其抽象方法和成員,並且將抽象類的其他方法的一些默認實現,您可能會重寫或不重寫。

- 編輯 - 忘了提,埃裏克提醒我

最後,只要你想,你可以實現多個接口,但只能繼承一個類(即它抽象的或沒有)。選擇之前請牢記這一點。

11

抽象類是一個類,它不實現它的一些方法。顯然它不能被實例化。您必須從一個抽象類繼承並在另一個類中實現抽象方法。

接口根本沒有類(所以不要稱它們爲接口類)。接口定義方法的簽名而不需要任何實現。接口也沒有成員字段。如果您在類中實現接口,則必須爲接口提供的方法提供實現。

爲某些東西定義一個通用的API是有意義的,它可以有完全不同的實現。抽象類對於主要相同的類更有用,但有一些細微的差別。你可以結合這兩種方法。

一個很好的例子是Java類庫的collections framework。你有接口List,它定義了List的行爲。一些實現例如是ArrayList和LinkedList。因爲它們的行爲相似,所以兩者都適用的東西在抽象類AbstactList中實現,都繼承了這一點。

1

當您構建繼承層次結構時,將使用抽象類。但是,大多數繼承層次不應該太「深」(即繼承層次太多)。許多面向對象的設計書籍都會支持接口而不是繼承(我讀過的一本書曾經引用開發人員的話說,「繼承是你不會實現的單一最酷的[面向對象]特性」),因爲這允許爲類分配行爲「通過合同「,其中合同是界面。

值得注意的是samuelcarrijo的答案 - 如果你想有一個方法的默認實現,你將不得不使用一個抽象類,該方法具有該方法的具體實現以賦予其默認實現。這個默認實現可以在子類中重寫。

希望這會有所幫助!

2

SamuelCarrijo好像已經很好地回答了這個問題。

另外對於Java,一些框架需要使用接口。我正在考慮(比如說)dynamic proxies,或者一些客戶端/服務器代理框架。這是因爲他們在對象上使用自省來確定由對象實現的接口實現的方法。所以偶爾你必須爲一個對象實現一個接口,或許你通常不會打擾。

注意這個接口的原因是特定於Java的。

15

關鍵的區別在於,你可以在一個類中有多個接口,但只有extend一個抽象類。這是因爲抽象類也可以定義存儲數據的字段,而接口不能。

3

查看界面基本上是一個「合同」。當你定義一個接口時,你正在定義一個合約。在抽象類被擴展的地方,接口被實現。

讓我們來看一個例子。

public interface Friend { 
void hello(); 
} 

現在您已經定義了一個合同,說其希望實現Friend任何類需要的方法hello()提供的定義。

這是一個實現:

public class myFriend implements Friend { 
public void hello() 
println("Done"); 
} 

現在myFriend已經履行了合同。現在的問題是:應該在哪裏使用接口?

接口幫助您定義必須實施的行爲。假設你有一個定義了一些功能的類A,只有在定義特定行爲(方法)時,您才希望其他類應該使用此類功能。您在界面方面強制執行此限制。