何时使用抽象类或接口?

时间:2009-08-03 09:59:18

标签: java interface abstract-class

为什么要创建抽象类或接口类,或者何时应该使用抽象类或接口类?

6 个答案:

答案 0 :(得分:40)

当您只想声明一个类必须具有哪些方法和成员时,使用接口。任何实现该接口的人都必须声明并实现接口列出的方法。

如果您还想要一个默认实现,请使用抽象类。扩展抽象类的任何类都必须只实现其抽象方法和成员,并且将具有抽象类的其他方法的一些默认实现,您可以覆盖或不重写。

- 编辑 - 忘了提,Earwicker提醒我

最后,您可以根据需要实现任意数量的接口,但只能扩展一个类(无论是抽象的还是抽象的)。在选择之前请记住这一点。

答案 1 :(得分:16)

关键的区别在于,您可以implement一个类中的多个接口,但只能extend一个抽象类。这是因为抽象类还可以定义存储数据的字段,而接口则不能。

答案 2 :(得分:11)

抽象类是一个类,它至少包含一个抽象方法,或者您也可以将所有方法都设计为抽象方法。显然它无法实例化。您必须从一个抽象类继承并在继承类中实现抽象方法(即扩展抽象类的类)。

接口根本不是类(因此不要将它们称为接口类)。接口定义方法的签名而无需任何实现。接口也没有成员字段。如果在类中实现接口,则必须为接口提供的所有方法提供实现。

为某些东西定义一个通用API是有意义的,它可以有完全不同的实现。抽象类对于主要相同的类更有用,但有一些细微的差别。您可以将两种方法结合起来。

一个很好的例子是Java类库的collections framework。您有接口List,它定义了Lists的行为方式。一些实现例如是ArrayList和LinkedList。因为它们的行为相似,所以两者都相同的东西在抽象类AbstactList中实现,都继承了它。

答案 3 :(得分:3)

请参阅界面基本上是“合同”。在定义界面时,您正在定义合同。在扩展抽象类的地方,接口是实现的。

让我们考虑一个例子。

public interface Friend {
void hello();
}

现在您已经定义了一个合同,该合同规定任何想要实现Friend的类都需要为方法hello()提供定义。

这是一个实现:

public class myFriend implements Friend {
public void hello()
println("Done");
}

现在myFriend已经履行了合同。现在的问题是:接口应该在哪里使用?

接口可帮助您定义必须实现的行为。假设你有一个定义了一些功能的A类。您希望其他类仅在定义特定行为(方法)时才使用此类功能。您可以在界面方面强制执行此限制。

答案 4 :(得分:2)

SamuelCarrijo似乎已经很好地回答了这个问题。

除了Java之外,一些框架还需要一个可以使用的接口。我想(比如说)dynamic proxies,或者一些客户端/服务器代理框架。这是因为它们对对象使用内省来确定由对象实现的接口实现的方法。所以偶尔你必须为一个对象实现一个接口,或许你通常不会打扰它。

注意接口的这个原因是特定于Java的。

答案 5 :(得分:1)

在构建继承层次结构时使用抽象类。但是,大多数继承层次结构不应该太“深”(即继承的层次太多)。许多面向对象的设计书籍都倾向于接口而不是继承(我读过的一本书曾引用开发人员的话说“继承是你不会实现的最酷的[面向对象]功能”),因为它允许为类分配行为“通过合同“,合同是界面。

值得注意的是samuelcarrijo的答案 - 如果你想要一个方法的默认实现,你将不得不使用一个具有该方法的具体实现的抽象类来为它提供一个默认实现。可以在子类中重写此默认实现。

希望这有帮助!