一个接口是一个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