这可能是一个通用的OOP问题。我想在接口和抽象类的使用基础上做一个通用的比较。

什么时候需要使用接口,什么时候需要使用抽象类?


当前回答

什么时候选择抽象类而不是接口?

如果计划在程序/项目的整个生命周期中更新基类,最好允许基类是一个抽象类 如果有人试图为层次结构中密切相关的对象构建主干,那么使用抽象类是非常有益的

什么时候选择接口而不是抽象类?

如果不需要处理大量的层次结构类型的框架,那么接口将是一个很好的选择 因为抽象类不支持多重继承(菱形问题),所以接口可以挽救局面

其他回答

答案因语言而异。例如,在Java中,一个类可以实现(继承)多个接口,但只能继承一个抽象类。所以接口给了你更多的灵活性。但在c++中却不是这样。

类只能继承自一个基类,因此如果您想使用抽象类为一组类提供多态性,它们必须全部继承自该类。抽象类也可以提供已经实现的成员。因此,您可以使用抽象类确保一定数量的相同功能,但不能使用接口。

下面是一些建议,可以帮助您决定是使用接口还是抽象类为组件提供多态性。

If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created in that way. If a new version of an interface is required, you must create a whole new interface. If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes. If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class. If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.

抄袭: http://msdn.microsoft.com/en-us/library/scsyfw1d%28v=vs.71%29.aspx

如果你认为java是面向对象语言,

“接口不提供方法实现”在Java 8启动后不再有效。现在java为默认方法提供了接口实现。

简单来说,我想用

接口:通过多个不相关的对象实现一个契约。它提供了“HAS A”功能。

抽象类:在多个相关对象之间实现相同或不同的行为。它建立了“IS A”关系。

Oracle网站提供了接口和抽象类之间的关键区别。

考虑使用抽象类,如果:

您希望在几个密切相关的类之间共享代码。 您希望扩展抽象类的类具有许多公共方法或字段,或者需要除public以外的访问修饰符(例如protected和private)。 您希望声明非静态或非final字段。

考虑使用接口,如果:

您希望不相关的类实现您的接口。例如,许多不相关的对象都可以实现Serializable接口。 您希望指定特定数据类型的行为,但不关心由谁实现其行为。 您希望利用类型的多重继承。

例子:

抽象类(IS一个关系)

Reader是一个抽象类。

BufferedReader是一个Reader

FileReader是一个阅读器

FileReader和BufferedReader用于一个共同的目的:读取数据,它们通过Reader类相互关联。

接口(具有功能)

Serializable是一个接口。

假设您的应用程序中有两个实现Serializable接口的类

Employee实现Serializable

游戏实现Serializable

在这里,你不能通过Serializable接口在员工和游戏之间建立任何关系,这是为了不同的目的。两者都能够序列化状态,比较到此结束。

看看这些帖子:

我应该如何解释接口和抽象类之间的区别?

当您需要向一组(相关或不相关的)对象添加额外的功能时,接口比抽象类表现得更好。如果你不能给他们一个基本抽象类(例如,他们是密封的或已经有一个父类),你可以给他们一个虚拟的(空的)接口,然后简单地为这个接口编写扩展方法。

纯粹在继承的基础上,你可以使用一个抽象的定义清晰的后代,抽象的关系(例如动物->猫)和/或需要继承虚拟或非公共属性,特别是共享状态(接口不支持)。

你应该尝试使用组合(通过依赖注入)而不是继承,并且注意接口作为契约支持单元测试、关注点分离和(语言变化)多重继承,而抽象则不能。