【发布时间】:2011-03-11 04:17:31
【问题描述】:
我一直在研究 C#,并且总是在接口和抽象类之间应该选择什么之间感到困惑。有人可以帮忙解决这个问题吗?
谢谢,
【问题讨论】:
-
stackoverflow.com/questions/2308786/… 第一个答案有很多链接
我一直在研究 C#,并且总是在接口和抽象类之间应该选择什么之间感到困惑。有人可以帮忙解决这个问题吗?
谢谢,
【问题讨论】:
想想像contract 这样的接口,您正在指定您希望该接口的使用者实现的东西。
另一方面,当您有一些需要为该类实现的代码但不是全部时,抽象类很有用。并且可以为抽象类的子类需要实现的部分声明抽象方法。请记住,抽象方法必须由子类实现,但您也可以通过普通的 private/public/protected/etc 在类本身中提供自己的代码。方法。
因此,如果您只是在编写希望子类实现的合同,那么请考虑接口。但是,如果您正在编写更多是“模式”的东西,其中您可能拥有所有子实现通用的一些方法实现(但不是全部),那么您应该考虑抽象类。
【讨论】:
两者都不是“更好”——它们有不同的目的。
接口适用于当您需要定义一组具有相似语义的常用方法,但定义这些方法的类不能从同一源继承,并且可能具有完全不同的实现。
抽象类适用于您希望部分实现某些功能,但将重要部分委托给子类的情况。抽象类的实现比接口的实现更受限制,因为实现类必须从抽象类继承,并且它们不能覆盖基类中不是virtual 或abstract 的部分.
【讨论】:
这取决于你想要做什么。当您具有具有通用状态的通用功能时,抽象类是很好的。即使您使用抽象类,提供接口通常也很有帮助,因为您并不总是需要访问状态,并且其他类可能会在没有该状态的情况下实现接口(例如测试存根)。
如果您只需要辅助方法(无状态,只需组合方法调用),那么我更喜欢使用带有辅助函数扩展方法的接口(例如重载)。
【讨论】:
已经有一些代码答案,但我想补充一个很多开发人员忘记的另一种观点。
如果您在公共 API 中使用接口,那么您已将自己承诺给它包含的那些成员,并且只承诺给那些成员。如果您尝试向界面添加某些内容,那么这是一个版本破坏性更改。为什么?因为每个类都必须实现接口中的每个成员。使用您的 API 的代码将停止编译。
抽象类不会受到同样的限制,因为您可以添加方法并为它们提供合理的默认实现。这样子类就不会更明智,也不会受到更改的影响。
【讨论】:
抽象基类最好在内部使用,以满足您自己的需要。当您编写需要与其他人的代码交互的东西时,接口会更好。主要原因是 C# 不支持多重继承。
因此,例如,如果您提供了一个 PluginBase 抽象基类,您希望消费者对其进行子类化以便为您的系统提供插件,那么您已经强制它们进入您的基类并严格限制它们。 IPlugin 接口更加灵活。
【讨论】: