如何决定是使用接口还是抽象类?

时间:2010-07-02 15:46:35

标签: c# oop

我已经进入C#并且总是在界面和抽象类之间应该选择什么之间感到困惑。有人可以帮忙解决这个问题吗?

谢谢,

5 个答案:

答案 0 :(得分:8)

想象一个像contract这样的界面,你正在指定一些你期望该界面的消费者实现的东西。

另一方面,当您需要为类实现的某些代码时,抽象类很有用,但不是全部。您可以为需要由抽象类的子类实现的部分声明抽象方法。请记住,抽象方法必须由子类实现,但您也可以通过普通的private / public / protected / etc在类本身内提供自己的代码。方法

因此,如果您只是编写一个您希望实现子类的合同,那么请考虑接口。但是如果你正在写一些更像是“模式”的东西,你可能会有一些方法实现(但不是全部)对所有子实现都是通用的,那么你应该考虑抽象类。

答案 1 :(得分:6)

两者都没有“更好” - 它们有不同的目的。

  • 接口用于何时需要定义一组具有相似语义的公共方法,但定义这些方法的类不能从同一个源继承,并且可能具有完全不同的实施。

  • 抽象类用于部分实现某些功能,但将重要部分委托给子类。抽象类的实现比接口的实现更受限制,因为实现类必须从抽象类继承,并且它们不能覆盖不是virtual或{的基类部分。 {1}}。

答案 2 :(得分:2)

这取决于你想要做什么。当您具有共同状态的通用功能时,抽象类很好。即使您使用抽象类,提供接口通常也很有帮助,因为您并不总是需要访问状态,而其他类可能会在没有该状态的情况下实现接口(例如测试存根)。 p>

如果你只需要辅助方法(没有状态,只是编写方法调用),那么我更喜欢使用带有扩展方法的接口来实现辅助函数(例如重载)。

答案 3 :(得分:1)

已经有一些代码答案,但我想添加许多开发人员忘记的另一个视角。

如果您在公共API中使用接口,那么您已经将自己承诺给它包含的成员,并且只承认那些成员。如果您尝试向界面添加内容,那么它就是一个版本更改。为什么?因为每个类都必须实现接口中的每个成员。使用您的API的代码将停止编译。

抽象类不会受到同样的限制,因为您可以添加方法并为它们提供合理的默认实现。然后,子类不是更明智的,也不会受到更改的影响。

答案 4 :(得分:0)

抽象基类最适合内部使用,以满足您的需求。当您编写需要与其他人的代码交互的内容时,接口会更好。主要原因是C#不支持多重继承。

因此,例如,如果您提供了一个PluginBase抽象基类,您希望使用者为了为系统提供插件而进行子类化,那么您已经强制它们进入基类并严格限制它们。 IPlugin界面更加灵活。