需要抽象类和接口吗?

时间:2008-11-27 04:42:39

标签: java interface abstract-class

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

5 个答案:

答案 0 :(得分:20)

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

接口不能包含。

答案 1 :(得分:8)

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

让我们举一个具体的例子。我们将研究如何从摘要CheckingAccount制作SavingsAccountAbstractBankAccount,并了解如何使用界面区分这两种类型的帐户。

首先,这是一个抽象类AbstractBankAccount

abstract class AbstractBankAccount
{
    int balance;
    public abstract void deposit(int amount);
    public abstract void withdraw(int amount);
}

我们的帐户余额为balance,两个方法depositwithdraw必须由子类实施。

正如我们所看到的,抽象类声明了如何定义银行账户的结构。正如@Uri在他的回复中提到的,这个抽象类有一个 state ,它是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方法可以增加兴趣,但话说再次,并不是客户自己存入利息。因此,如果我们有另外一种方法可以向账户中添加资金,特别是利息,例如accrueInterest方法,可能会更清楚。

我们可以直接在SavingsAccount中实施该方法,但我们可能会有更多银行帐户类型,以便将来产生兴趣,因此我们可能希望创建一个InterestBearing接口,其中包含accrueInterest 1}}方法:

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接口以进行另一个计划帐户。

可以将InterestBearing界面视为向不同的类添加常用功能。如果没有产生任何利息,那么拥有一个处理支票账户利息的功能是没有意义的。

因此,在某种情况下,抽象类和接口确实可以共存并协同工作。

答案 2 :(得分:4)

抽象类v / s接口是一个主题,它会为刚接触Java的人带来许多好奇心/兴趣/困惑,并希望深入挖掘。

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

答案 3 :(得分:2)

有几个原因可能会让您更喜欢在接口上使用无实现的抽象类:

  • 可以在编译时捕获某些不可能的强制转换和instanceof操作。
  • 您可以选择在更高版本中添加具体方法。
  • 多年前曾经有过显着的性能优势。
  • 从高度模糊的安全角度来看,您无法通过创建预先存在的类和抽象类的子类来获得预先存在的类来实现这些方法。

但另一方面,接口Java关键字允许更清晰的源。

答案 4 :(得分:0)

通常,接口描述您的代码应该使用的公共API,而抽象基类最好保留为实现细节,其中可以保留公共代码或状态,以减少任何实现类中的重复。

通过在API中使用接口,人们(包括您)可以更轻松地针对您的类编写测试代码,因为您可以使用测试类,例如,不依赖于任何外部资源,或者哪些展示显而易见的各种不良但难以模拟的现实生活行为。

所以java提供了List接口,而AbstractList抽象基类则“最小化了实现接口所需的工作量......”