Java 需要抽象类和接口吗?

Java 需要抽象类和接口吗?,java,interface,abstract-class,Java,Interface,Abstract Class,接口是100%抽象类,因此我们可以使用接口进行高效编程。是否存在抽象类优于接口的情况?当您确实打算创建具体类时,会使用抽象类, 但是要确保在所有子类中都有一些公共状态 或者对于某些操作可能的通用实现 接口两者都不能包含。抽象类v/s接口是一个话题,对于任何一个Java新手来说,都会产生很多好奇/兴趣/困惑,并希望深入挖掘 提供有关该主题的详细说明。是的,抽象类和接口都有位置 让我们举一个具体的例子。我们将研究如何从抽象的AbstractBankAccount创建CheckingAccount和S

接口是100%抽象类,因此我们可以使用接口进行高效编程。是否存在抽象类优于接口的情况?

当您确实打算创建具体类时,会使用抽象类, 但是要确保在所有子类中都有一些公共状态 或者对于某些操作可能的通用实现


接口两者都不能包含。

抽象类v/s接口是一个话题,对于任何一个Java新手来说,都会产生很多好奇/兴趣/困惑,并希望深入挖掘


提供有关该主题的详细说明。

是的,抽象类和接口都有位置

让我们举一个具体的例子。我们将研究如何从抽象的
AbstractBankAccount
创建
CheckingAccount
SavingsAccount
,并了解如何使用接口区分这两种类型的帐户

首先,这里有一个抽象类
AbstractBankAccount

abstract class AbstractBankAccount
{
    int balance;
    public abstract void deposit(int amount);
    public abstract void withdraw(int amount);
}
我们的账户余额为
balance
,两种方法
存款
取款
,必须由子类实现

正如我们所看到的,抽象类声明了银行账户应该如何定义的结构。正如@Uri在他的回答中提到的,这个抽象类有一个状态,即
balance
字段。这在接口上是不可能的

现在,让我们将
AbstractBankAccount
子类化,以创建一个
CheckingAccount

class CheckingAccount extends AbstractBankAccount
{
    public void deposit(int amount)
    {
        balance += amount;
    }

    public void withdraw(int amount)
    {
        balance -= amount;
    }
}
在这个子类
CheckingAccount
中,我们实现了两个抽象类——这里没有什么太有趣的东西

现在,我们如何实现
SavingsAccount
?它不同于
检查账户
,因为它会获得利息。通过使用
存款
方法可以增加利息,但再次强调,客户并不是在自己存款利息。因此,如果我们有另一种向账户中添加资金的方法,特别是利息,例如,
AccounteInterest
方法,可能会更清楚

我们可以在
SavingsAccount
中直接实现该方法,但我们可能会有更多的银行账户类型可以在将来累积利息,因此我们可能希望制作一个
利息负担
界面,该界面具有
累积利息
方法:

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;
    }
}
现在,如果我们想创建另一种类型的帐户,比如一个
PremiumSavingsAccount
,我们可以创建
AbstractBankAccount
的一个子类,并实现
利息负担
接口来创建另一个计息帐户

InterestBearing
界面可以看作是为不同的类添加了一个公共特性。在支票账户不产生任何利息的情况下,设置处理利息的功能是没有意义的


因此,在一种情况下,抽象类和接口确实存在共存和协同工作的地方。

一般来说,接口描述了代码应该使用的公共API,而抽象基类最好作为实现细节保存,可以保存公共代码或状态,减少任何实现类中的重复

通过在API中使用接口,人们(包括您)可以更容易地针对您的类编写测试代码,因为您可以使用不依赖于任何外部资源的测试类,或者在现实生活中表现出明显的不良但难以模拟的测试类


因此,java提供了List接口和AbstractList抽象基类,以“最小化实现”接口所需的工作量…

您可能更喜欢无实现抽象类而不是接口,原因如下:

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;
    }
}
  • 某些不可能的强制转换和操作实例可以在编译时捕获
  • 您可以选择在更高版本中添加具体方法
  • 许多年前,曾经有一个显著的性能优势
  • 从一个高度模糊的安全性角度来看,您无法通过创建预先存在的类和抽象类的子类来获得预先存在的类来实现这些方法

但另一方面,interface Java关键字允许更干净的源代码。

我将继续定义接口,即使定义抽象类也是如此。它使您的代码更易于测试,并减少与特定实现的耦合。在我的代码中,我通常会考虑到接口的接口(听起来很傻),并使用抽象类作为标准实现和状态的基础。您说:“并使用抽象类作为标准实现和状态的基础,您可能的意思是:”并使用抽象类作为“通用实现”的基础和国家“@Shwa:我的错。我应该更加注意我的评论。我只想补充一点,就是即使有一个通用的实现,也要注意始终编写接口的约束。我确实看到了很多代码,即使将变量声明为接口类型,也会根据抽象类的工作进行假设。您提供的链接非常有用。它清楚地使用了抽象和接口。谢谢,朋友。您在我的查询中给了我宝贵的想法。