一個接口是一個100%抽象類,所以我們可以使用一個接口來進行高效編程。有什麼情況下抽象類比接口更好?需要抽象類以及接口?
回答
抽象類是用來當你打算創建一個具體類, 但要確保有在所有子類 一些常見的狀態或對某些操作可能共同實施。
接口不能包含任何一個。
抽象類v/s接口是一個話題,對於任何新來的Java人都會產生很多好奇心/興趣/困惑,並想深入挖掘。
This article提供了關於該主題的詳細解釋。
是的,有抽象類和接口的地方。
讓我們來舉一個具體的例子。我們將研究如何從摘要AbstractBankAccount
製作CheckingAccount
和SavingsAccount
,並瞭解我們如何使用界面區分這兩種類型的帳戶。
要開始了,這裏是一個抽象類AbstractBankAccount
:
abstract class AbstractBankAccount
{
int balance;
public abstract void deposit(int amount);
public abstract void withdraw(int amount);
}
我們的帳戶餘額balance
和兩個方法deposit
和withdraw
必須由子類實現。
正如我們所看到的,抽象類聲明瞭應如何定義銀行帳戶的結構。正如@Uri在他的回覆中提到的,這個抽象類有狀態,它是balance
字段。這對於一個界面來說是不可能的。
現在,讓我們的子類AbstractBankAccount
做出CheckingAccount
class CheckingAccount extends AbstractBankAccount
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
}
在這一小類CheckingAccount
,我們實施了兩個抽象類 - 沒有什麼太有趣了這裏。
現在,我們該如何執行SavingsAccount
?它不同於CheckingAccount
,因爲它會獲得利益。通過使用deposit
方法可以增加興趣,但是再一次,它不像顧客自己放置興趣。因此,如果我們有另一種向賬戶中添加資金的手段,特別是爲了利息,比如說,可以更清楚地說明一種方法。
我們可以直接實現方法SavingsAccount
,但我們可能能夠在未來的計息更多的銀行帳戶類型,所以我們可能要做出InterestBearing
接口具有accrueInterest
方法:
interface InterestBearing
{
public void accrueInterest(int amount);
}
所以,我們現在可以做出SavingsAccount
類可以通過實現InterestBearing
接口獲得利益:現在
class SavingsAccount extends AbstractBankAccount implements InterestBearing
{
public void deposit(int amount)
{
balance += amount;
}
public void withdraw(int amount)
{
balance -= amount;
}
public void accrueInterest(int amount)
{
balance += amount;
}
}
,如果我們想使anothe r類型的賬戶,例如PremiumSavingsAccount
,我們可以製作AbstractBankAccount
的子類並實現InterestBearing
接口以創建另一個有息賬戶。
InterestBearing
接口可以看作是將一個共同特徵添加到不同的類。在沒有任何利息的情況下,擁有一個功能來處理支票賬戶中的利息是沒有意義的。
所以,的確是有兩個抽象類和接口共存,並且在一種情況下一起工作的地方。
在一般情況下,接口描述,你的代碼應該使用公共API,而抽象基類最好保存爲一個實現細節,可以保留常見的代碼或狀態,以減少任何實現類中的重複。
通過在您的API中使用接口,人們(包括您)可以更輕鬆地針對您的類編寫測試代碼,因爲您可以使用測試類,例如,不依賴於任何外部資源,或者展現出明顯的壞 - 但是難以模擬的現實生活行爲。
所以Java提供了List接口,而AbstractList的抽象基類,以「最大限度地減少實現所需的努力」的界面...
有幾個原因,你可能更喜歡無實現的抽象類通過接口:
- 某些不可能的強制轉換和instanceof操作可以在編譯時捕獲。
- 您可以選擇在更高版本中添加具體方法。
- 許多年前曾經有一個顯着的性能優勢。
- 從一個不起眼的高度安全的角度看,你不能讓一個已經存在的類創建預先存在的類的子類和抽象類來實現的方法。
但在另一方面,該接口的Java關鍵字允許更清潔源。
- 1. 接口:需要一個抽象常量?
- 2. 擴展已經實現接口的抽象類的類是否需要接口?
- 3. 需要具體類的子類以及接口的C#類型
- 4. 抽象類,類,接口
- 5. 爲什麼我們在抽象類存在時需要接口?
- 6. 爲什麼我們有抽象類時需要接口?
- 7. 當我需要在Java中使用抽象類和接口?
- 8. 需要幫助瞭解實現接口的抽象類
- 9. 您何時需要以接口的形式創建抽象?
- 10. 抽象類返回接口
- 11. 與接口和抽象類
- 12. PHP抽象類和接口
- 13. 與抽象類的接口
- 14. 抽象類實現接口
- 15. 接口中的抽象類?
- 16. 抽象類V/s接口
- 17. 抽象類或SoftDelete接口
- 18. C#接口和抽象類
- 19. 抽象類MouseAdapter與接口
- 20. 抽象類和接口
- 21. 接口vs 100%抽象類
- 22. 接口與抽象類
- 23. 100%抽象類與接口
- 24. 純抽象類和接口
- 25. 抽象接口
- 26. c#接口,抽象類,強制繼承類不抽象類
- 27. php抽象類和涉及靜態方法的接口?
- 28. 類不抽象的Java?接口使用涉及
- 29. 要滿足要求的接口或抽象類
- 30. 爲什麼要使用抽象接口?
即使定義了抽象類,我也會繼續定義接口。它使你的代碼更友善,並且更少地耦合到特定的實現。 – tvanfosson 2008-11-27 04:58:44
是的,當然,我同意100%。在我的代碼中,我通常將接口界定爲接口(聽起來很愚蠢),並使用抽象類作爲標準實現和狀態的基礎。 – Uri 2008-11-27 05:09:22
你說:「並且使用抽象類作爲標準實現的基礎和狀態 你可能的意思是: 」並且使用抽象類作爲「普通實現」的基礎和狀態「 – Shaw 2008-11-27 06:36:41