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

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


当前回答

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

其他回答

抽象类可以有实现。

接口没有实现,它只是定义了一种契约。

也可能存在一些依赖于语言的差异:例如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

两者都是类定义的契约:

结论1:两种意图都是对象泛化

在定义抽象类时,它们也可以有默认实现。

结论2:区分存在于行为泛化设计中

在使用抽象类时,类只能从一个抽象类继承

结论3:抽象类在应用上存在局限性。它的意思是 行为概括的局限性。

最后结论-何时使用哪个:区分是在行为泛化层面

在类的行为设计中,如果功能在确定的类之间只是概念上的限制,换句话说,在确定的类之间是共享的,则使用抽象类。但如果功能比确定类更通用,或者我们可以/想要向其他类添加功能,则使用接口作为契约。

我的观点是:

接口基本上定义了一个契约,任何实现类都必须遵守(实现接口成员)。它不包含任何代码。

另一方面,抽象类可以包含代码,并且可能有一些标记为抽象的方法,继承类必须实现这些方法。

我很少使用抽象类的情况是,当我有一些默认功能时,继承类可能对重写不感兴趣,比如一个抽象基类,一些专门的类继承自它。

示例(非常基本的一个!):考虑一个名为Customer的基类,它具有抽象方法,如CalculatePayment(), CalculateRewardPoints()和一些非抽象方法,如GetName(), SavePaymentDetails()。

像RegularCustomer和GoldCustomer这样的专门的类将继承自Customer基类,并实现它们自己的CalculatePayment()和CalculateRewardPoints()方法逻辑,但是重用GetName()和SavePaymentDetails()方法。

您可以向抽象类(即非抽象方法)添加更多功能,而不会影响使用旧版本的子类。然而,向接口添加方法会影响实现它的所有类,因为它们现在需要实现新添加的接口成员。

具有所有抽象成员的抽象类类似于接口。