【问题标题】:How do I decide whether to use an interface or an abstract class?我如何决定是使用接口还是抽象类?
【发布时间】:2011-03-11 04:17:31
【问题描述】:

我一直在研究 C#,并且总是在接口和抽象类之间应该选择什么之间感到困惑。有人可以帮忙解决这个问题吗?

谢谢,

【问题讨论】:

标签: c# oop


【解决方案1】:

想想像contract 这样的接口,您正在指定您希望该接口的使用者实现的东西。

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

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

【讨论】:

    【解决方案2】:

    两者都不是“更好”——它们有不同的目的。

    • 接口适用于当您需要定义一组具有相似语义的常用方法,但定义这些方法的类不能从同一源继承,并且可能具有完全不同的实现。

    • 抽象类适用于您希望部分实现某些功能,但将重要部分委托给子类的情况。抽象类的实现比接口的实现更受限制,因为实现类必须从抽象类继承,并且它们不能覆盖基类中不是virtualabstract 的部分.

    【讨论】:

    • +1 。这个问题是“愚蠢的”,因为它与“什么更好 - 胡椒或盐”相同。两者都是有原因的,所以很明显 nooone 更好。如果是这样的话,就不会有这两种选择了,因为 C# 语言设计师是一个非常聪明的人。
    • 这个问题没有问哪个“更好”,所以它不是“愚蠢”
    • ...然而,这个问题在这方面已经被问过一百万次了...
    【解决方案3】:

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

    如果您只需要辅助方法(无状态,只需组合方法调用),那么我更喜欢使用带有辅助函数扩展方法的接口(例如重载)。

    【讨论】:

      【解决方案4】:

      已经有一些代码答案,但我想补充一个很多开发人员忘记的另一种观点。

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

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

      【讨论】:

      • 我同意,这些问题经常被忽略。接口只写一次,从不修改,尽管扩展方法增加了一些扩展接口的能力。抽象类也允许您更具体地了解需求,例如,通过实现合同或异常处理,这是无法通过接口完成的。
      • 这里当然没有正确的答案,但是我们需要考虑组合重于继承的原则。此外,一个类总是可以在不破坏向后兼容性的情况下实现额外的可扩展接口,但抽象基类删除了派生类中的继承选择。
      【解决方案5】:

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

      因此,例如,如果您提供了一个 PluginBase 抽象基类,您希望消费者对其进行子类化以便为您的系统提供插件,那么您已经强制它们进入您的基类并严格限制它们。 IPlugin 接口更加灵活。

      【讨论】:

        猜你喜欢
        • 2021-12-17
        • 1970-01-01
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 2011-05-22
        • 1970-01-01
        • 2012-09-12
        • 2010-10-08
        相关资源
        最近更新 更多