需要抽象类和接口吗?
接口是100%的抽象类,因此我们可以使用接口进行高效的编程。 有没有抽象类比接口更好的情况?
An interface is a 100% abstract class, so we can use an interface for efficient programming. Is there any situation where an abstract class is better than an interface?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
当您确实打算创建具体类时,可以使用抽象类,
但想要确保所有子类中有一些共同状态
或某些操作的可能通用实现。
接口不能包含其中任何一个。
Abstract classes are used when you do intend to create a concrete class,
but want to make sure that there is some common state in all the subclasses
or a possible common implementation for some operations.
Interfaces cannot contain either.
是的,抽象类和接口都有一席之地。
让我们来看一个具体的例子。 我们将研究如何从抽象的
AbstractBankAccount
中创建CheckingAccount
和SavingsAccount
,并了解如何使用接口区分这两种类型账户。首先,这里有一个抽象类
AbstractBankAccount
:我们有帐户余额
balance
和两个方法deposit
和withdraw
> 必须由子类实现。正如我们所看到的,抽象类声明了如何定义银行帐户的结构。 正如@Uri 在他的回复中提到的,这个抽象类有一个状态,即
balance
字段。 这对于接口来说是不可能的。现在,让我们对
AbstractBankAccount
进行子类化以创建一个CheckingAccount
在这个子类
CheckingAccount
中,我们实现了两个抽象类——这里没有什么太有趣的。现在,我们如何实现
SavingsAccount
? 它与CheckingAccount
的不同之处在于它会获得利息。 可以通过使用deposit
方法来增加利息,但话又说回来,这并不是客户自己存入利息。 因此,如果我们有另一种向账户添加资金的方法,特别是利息,例如,accrueInterest 方法,情况可能会更清楚。我们可以直接在
SavingsAccount
中实现该方法,但是我们可能有更多可以在未来产生利息的银行账户类型,因此我们可能需要创建一个InterestBearing
接口,其中包含accrueInterest
方法:因此,我们现在可以创建一个
SavingsAccount
类,它可以通过实现InterestBearing
接口来获得利息:现在,如果我们想要创建另一种类型的帐户,例如
PremiumSavingsAccount
,我们可以创建AbstractBankAccount
的子类并实现InterestBearing
接口来创建另一个计息帐户帐户。InterestBearing
接口可以看作是为不同的类添加一个公共功能。 当支票账户不产生任何利息时,拥有处理其利息的功能是没有意义的。因此,抽象类和接口确实可以在一种情况下共存和协同工作。
Yes, there is a place for both abstract classes and interfaces.
Let's go with a concrete example. We'll look into how to make a
CheckingAccount
andSavingsAccount
from an abstractAbstractBankAccount
and see how we can use an interface differentiate the two types of accounts.To start off, here's an abstract class
AbstractBankAccount
:We have the account balance as
balance
and two methodsdeposit
andwithdraw
that must be implemented by the subclasses.As we can see, an abstract class declares the structure of how bank accounts should be defined. As @Uri mentions in his response, there is a state to this abstract class, which is the
balance
field. This would not be possible with an interface.Now, let's subclass
AbstractBankAccount
to make aCheckingAccount
In this subclass
CheckingAccount
, we implemented the two abstract classes -- nothing too interesting here.Now, how could we implement
SavingsAccount
? It is different from aCheckingAccount
in that it will gain interest. The interest could be increased by using thedeposit
method, but then again, it's not as if the customer is depositing the interest him/herself. Therefore, it might be more clearer if we had another means of adding money into an account, specifically for interest, say, anaccrueInterest
method.We could directly implement the method in
SavingsAccount
, but we may have more bank account types that can accrue interest in the future, so we may want to make anInterestBearing
interface that has theaccrueInterest
method:So, we now can make an
SavingsAccount
class that can gain interest by implementing theInterestBearing
interface:Now, if we want to make another type of account, say a
PremiumSavingsAccount
, we can make a subclass of theAbstractBankAccount
and implement theInterestBearing
interface to make another interest-bearing account.The
InterestBearing
interface can be seen as adding a common feature to different classes. It would have not have made sense to have a feature to deal with interest in a checking account when it doesn't accrue any interest.So, there are indeed places for both abstract classes and interfaces to coexist and work together in one situation.
抽象类与接口是一个让任何刚接触 Java 并想要深入挖掘的人产生很多好奇/兴趣/困惑的主题。
这篇文章提供了详细的解释关于这个话题。
Abstract class v/s interface is one topic that generates lot of curiosity/interest/confusion for anyone new to Java and wants to dig deeper.
This article provides a detailed explanation on the topic.
您可能更喜欢无实现的抽象类而不是接口,原因如下:
但另一方面,interface Java 关键字允许更清晰的源代码。
There a couple of reasons why you might prefer an implementation-free abstract class over an interface:
But on the other hand, the interface Java keyword allows cleaner source.
一般来说,接口描述了代码应该使用的公共 API,而抽象基类最好保留为实现细节,其中可以保留公共代码或状态,以减少任何实现类中的重复。
通过在 API 中使用接口,人们(包括您)可以更轻松地针对您的类编写测试代码,因为您可以使用不依赖于任何外部资源的测试类,或者表现出显式类型的测试类。糟糕但难以模拟现实生活中的行为。
所以java提供了List接口,以及AbstractList抽象基类来“最小化实现”接口所需的工作......
In general, interfaces describe the public API that your code should use, whereas abstract base classes are best kept as an implementation detail, where common code or state can be kept, to reduce duplication in any implementing classes.
By using interfaces in your API, it becomes easier for people (including you) to write test code against your classes, since you can use test classes that, for example, don't depend on any external resources, or which exhibit explicit kinds of bad-but-difficult-to-simulate-in-real-life behaviour.
So java provides the List interface, and the AbstractList abstract base class to "minimize the effort needed to implement" the interface...