抽象类还是接口,哪种方式更正确?

8

在选择抽象类或接口时,有两种方法。微软解决方案和Oracle解决方案:


微软,设计指南:

使用抽象类(在Visual Basic中为MustInherit)而不是接口来解耦合同与实现。

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


Oracle,Java教程:

如果一个抽象类只包含抽象方法声明,则应该声明为接口。

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


我的问题是哪种方法是正确的?微软还是甲骨文解决方案?请注意,我认为在抽象类或接口之间选择不应取决于编程语言(Java或C#)。
3个回答

10

如果我正确地记得我的博客阅读,微软建议使用抽象类是因为可以通过抽象类重用实现,而接口无法实现这一点。

注意,您链接的微软页面是特定于编写代码库以在多个项目之间共享/重用的指南。在这种情况下,您很可能会自己编写接口的所有实现,可能在同一个程序集中。在单个产品或系统上工作的良好实践会有所不同。

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

  • 定义一个接口以指定合约
  • 创建实现该合约的抽象类,以提供对所有后代有用的任何公共实现
  • 接口的实现可以选择从基类开始,以方便起见,或者只是实现完全控制接口

.NET世界中常见的第四步是提供构建在接口上的方便扩展函数。


“在单个产品或系统上工作的良好实践会略有不同。” - Jeff B

7

这是两个不同情境下的陈述。

你所引用的 Microsoft 指南适用于“设计类库”,并且它指出优先使用抽象类的原因:可以在不破坏现有代码的情况下添加功能。

为了实现层级和其他边界之间的隔离和解耦,Microsoft 还建议使用接口。


+1 - 这是微软建议的关键原因。 - Joe

1

接口不包含实现 - 它是一份契约。它允许完全解耦。

如果我想提供一些通用实现,同时强制继承类提供一些特定于该类的实现,我会从接口转到抽象(基)类。这提供了稍微少一点的解耦。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接