【问题标题】:Use interface inheritance or just implement all the interfaces directly?使用接口继承还是直接实现所有接口?
【发布时间】:2010-02-27 04:13:31
【问题描述】:

我不一定看到接口继承接口的巨大好处。

考虑下面三个接口,第三个继承另外两个

interface IOne {
}

interface ITwo {
}

// interface inheritance
interface IAll : IOne, ITwo {
}

是不是最好

class C : IOne, ITwo { ... }

class C : IAll { ... }

如果后者可能是有益的,那么为什么不创建 IAll 以拥有 IOne 和 ITwo 的所有方法而不从它们继承呢?毕竟它是一个接口。

接口继承是否实用,而不仅仅是有用?

【问题讨论】:

  • 如果你有大量的继承接口,你可以使用这个技巧来缩短行长。否则,在我看来,这是不必要的混淆(除非两个接口可以自然地组合在一起)。

标签: c# .net inheritance interface


【解决方案1】:

考虑接口“继承”的一个好方法是完全忘记它被称为“继承”。毕竟,显然“基础”接口对“派生”接口没有任何功能。它所贡献的只是承诺会有某些成员。

类派生关系通常意味着“is-a-kind-of”关系。 NullReferenceException 是一种异常。接口派生关系根本不暗示这一点——说IEnumerable<T>IDisposable 的一种意义不大。

相反,接口继承的意思是“实现IEnumerable<T>的类型也必须实现IDisposable。也就是说,接口继承并不意味着“这是一种那种”,而是“这个的每一个实现都是也需要实现这一点”。

这是否使它更引人注目?

【讨论】:

  • 这是一个非常有用的措辞,我会尽量记住 :)
  • 但是interface IList<T> : ICollection<T>, IEnumerable<T>, ...; 怎么样?每个 IList 都是 ICollection,对吗?替代原则似乎成立。
  • @Henk:但首先与 ICollection 没有“是”关系。 ICollection 是一个接口;它代表“可以做”的关系,而不是“是一种”的关系。接口继承意味着“任何可以做列表功能的东西,也必须提供集合和序列的功能”。
  • 不要拖太久,但是如果 X 可以做 Y 可以做的任何事情,那么在我看来 X“是一种”Y。尤其是当 X 和 Y 只有“可以做”时,就像接口的情况一样。在类/接口边界上,我一直认为这是两个不冲突的观点,FileStream 实现 IDisposableList 从 IList 继承都是有用的,富有成效的概念。
  • 如果接口 X 继承了接口 Y,那么 X 是 Y 的 SUBSTITUTABLE,这是 IS-A 关系的一个关键方面。
【解决方案2】:

做语义正确的事情。不要为了省去输入额外的界面而做任何事情。

如果 'IAll' 是一个在你的程序中有意义的概念,那好吧,使用它。如果这只是不输入“IFirst,ISecond”的一种方式,请不要这样做。

【讨论】:

    【解决方案3】:

    可能有些方法需要IAll 参数——因此,如果您满足实现整个IAll 的要求,那么这样做会很方便,而不是只实现它扩展的每个接口!

    当然,接口通常不是空的,因此实现一个和/或另一个(不同的,需要实现多种方法)会有特定的(可能很小)成本。例如,如果IFirst 有一个方法foo,而ISecond 有一个方法bar,那么将两者都扩展为IBoth 是非常有意义的,即使这不会添加更多需要的方法——它允许一个方法清楚地表达它需要一个具有both方法的参数,foo bar

    如果世界上的每个接口都是空的,那么它们的用途(更不用说用更多的空接口扩展它们)当然会更加更加可疑!-)

    【讨论】:

    • 我建议如果目的是使用一个接口来聚合其他接口(例如IOneITwo),最好明确指定该类实现所有三个接口,除非聚合类的名称会很明显(例如,如果接口被命名为 IFooIBarIFooAndBar,则后者的名称表明实现 IFooAndBar 的类同时实现 IFoo 和 @987654337 @)。
    【解决方案4】:

    是的,接口继承是实用的。接口背后的想法是,单个接口定义了一个松散的“契约”,描述了一组特定的功能。这样可以非常清晰地分离功能。

    通常,需要实现多个接口的类通过单独列出每个接口来实现,例如:

    class C : IOne, ITwo { ... }

    如果您需要从多个接口聚合功能的能力,那么您可能希望创建一个继承自其他接口的单个​​接口(例如您的IAll 接口)。虽然您可以这样做,但您通常不需要(或不想)这样做。

    【讨论】:

      【解决方案5】:

      我会采用第一种方法,这对我来说更清楚。第二个似乎是做作的,IMO。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-12
        • 2023-03-13
        • 1970-01-01
        • 2019-08-04
        • 2016-03-07
        • 2020-11-26
        • 1970-01-01
        相关资源
        最近更新 更多