抽象类或接口。哪种方式是正确的?

时间:2012-02-11 20:00:29

标签: c# java .net interface abstract-class

在抽象类或接口之间进行选择有两种方法。 Microsoft解决方案和Oracle解决方案:


Microsoft,设计指南:

使用抽象(Visual Basic中的MustInherit)类而不是接口来将合同与实现分离。

http://msdn.microsoft.com/en-us/library/ms229013.aspx


Oracle,Java教程:

如果抽象类只包含抽象方法声明,则应将其声明为接口。

http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html


我的问题是哪种方式是正确的? Microsoft或Oracle解决方案?请注意,我认为抽象类或接口之间的选择不应该依赖于编程语言(Java或C#)。

3 个答案:

答案 0 :(得分:10)

如果我记得我的博客正确阅读,微软使用抽象类的建议源于能够使用抽象类重用实现,这是你无法用界面做的事情。

另请注意,您链接到的Microsoft页面是编写代码库以跨多个项目共享/重用的专门指导。在这种情况下的可能性是您将自己编写接口的所有实现,可能在同一个程序集中。在单个产品或系统上工作的良好实践会有所不同。

我在多种语言的多个代码库中看到的一种常见方法是:

  • 定义用于指定合同的界面
  • 创建一个实现合同的抽象类,以提供对所有后代有用的任何常见实现
  • 然后,合同的实现可以选择从基类开始以方便使用,或者只是在需要完全控制时实现接口

.NET世界中常见的第四步是提供基于界面构建的便利扩展功能。

答案 1 :(得分:7)

对于不同的上下文,它们是2个语句。

您引用的Microsoft指南适用于“设计类库”。它说明了在那里支持抽象类的原因:你可以添加功能而不会破坏任何东西。

对于层和其他边界的分离和解耦,Microsoft也建议接口。

答案 2 :(得分:1)

接口没有实现 - 这是一个合同。它允许完全去耦。

如果我想提供一些常见的实现,同时强制继承类具体类以提供特定于该类的一些实现,我将从接口转到抽象(基类)类。这提供了一点点脱钩。

还要注意许多语言,如C#(和.net等语言,如VB.net等)以及Java不允许多重继承,因此接口成为允许类具有许多行为的一种方式。