【问题标题】:Interface inheritance VS class implementing two interfaces接口继承VS类实现两个接口
【发布时间】:2019-08-04 18:20:26
【问题描述】:

假设我们有两个接口:

interface Ilayer1 : Ilayer2
{
  string testMethod1();
}


interface Ilayer2
{
   string testMethod2();
}

class A: Ilayer1
{
   ...//implement all methods of Ilayer 1 and Ilayer2
}

所以我的问题是:

  1. 接口继承的目的是什么?既然他们可以有不同的方法签名来实现,那么Ilayer1通过继承Ilayer2得到了什么?
  2. 我们可以简单的去掉Ilayer1Ilayer2之间的继承关系,让A类实现两个接口为class A: Ilayer1, Ilayer2

【问题讨论】:

  • IPrimate : IMammal : IVertebrate 例如。其中每一个都为其继承的内容添加了其他人可能没有的特定特征。例如,您也可以使用 IFish : IVertebrate,因为鱼类和哺乳动物有一些不同的独立属性。
  • 所以你可以在Ilayer1的每个实现者中一遍又一遍地复制Ilayer2
  • 如果ILayer1ILayer2 添加了功能,或者ILayer2ILayer1 也使用的东西(如IComparable),那么它就很有意义了。现实世界的例子会更明显。

标签: c# oop inheritance interface


【解决方案1】:
  1. Ilayer1 继承 Ilayer2,这意味着任何实现 Ilayer1 的人都需要实现 testMethod1() testMethod2()为什么拥有它?为什么不?因为我们可以?我认为在具有大量接口的大型项目中,如果您需要指定某个类单独实现的所有接口,这可能会变得非常乏味(尽管在良好的SOLID 设计中,一个类通常不应该实现多个接口)。因此,您可以通过让它们实现其他接口来“分组”接口。您也可以使用接口继承'version' an interface
  2. 你可以。由你决定。有选择是好事。使用继承或单独实现接口。这取决于你。

接口可以从其他接口继承。一个类可能通过它继承的基类或通过其他接口继承的接口多次包含一个接口。但是,该类只能提供一次接口的实现,并且仅当该类将接口声明为类定义的一部分时 (class ClassName : InterfaceName)。如果由于继承了实现接口的基类而继承了接口,则基类提供接口成员的实现。但是,派生类可以重新实现任何虚拟接口成员,而不是使用继承的实现。 Source

【讨论】:

    【解决方案2】:

    一个现实生活中的例子:

    interface IShape 
    {
        double X { get; }
        double Y { get; }
    }
    
    interface IAreaShape : IShape
    {
        double GetArea();
    }
    
    interface IPerimeterShape : IShape
    {
        double GetPerimeter();
    }
    

    现在假设您有一个Rectangle : IAreaShape, IPerimeterShape 形状,您可以计算它的面积和周长。当您有一个IAreaShapeIPerimeterShape 类型的对象时,它必须是IShape。这是您第二个问题的答案。

    现在对于您的第一个问题,假设我们有一个Circle,我只能计算面积而不能计算周长。在这种情况下,我们只需将其声明为Circle : IAreaShape

    对于管理:List<IShape> shapes 可以同时使用圆形和矩形以及任何东西,只要它们实现了IShape(或IShape 的任何派生类型)。如果您不关心是否可以计算它们的面积或周长,则可以这样做,但您始终可以获取它们的 X 和 Y 坐标。

    【讨论】:

      【解决方案3】:

      这与类之间的继承语义相同。
      在 OOP 世界中,派生类型 当基类型是基类型的更具体版本时继承基类型 - 无论此类型是接口还是类,原则保持不变。

      这是一个来自 .Net 框架的示例:IList 接口继承了ICollection 接口,而IEnumerable 接口又继承了IEnumerable 接口。

      IEnumerable 接口提供了使用foreach 循环枚举所需的GetEnumerator() 方法。

      ICollection 添加了新功能:Count 属性和 CopyTo 方法。

      IList 增加了更多功能 - 索引器、AddRemove 方法等等。

      所以IListICollection 的更具体类型,IEnumerable 是更具体的类型。

      接口可以相互继承这一事实意味着您也可以在接口上而不只是在类上拥有polymorphic 观点 - 这可以在处理多个相互继承的接口时帮助您简化代码。

      这样做的另一个好处是,您可以在接口上声明扩展方法,并在任何实现此接口的类上使用它,无论是直接还是通过实现继承它的接口来间接实现 - 就像在类中一样。

      至于为什么不删除继承并分别实现这两个接口的问题——如果接口不相关——例如,在Control 类中(在 System.Windows.Forms 中)——它实现了许多接口,例如IDropTargetIComponent,它们是不相关的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-12
        • 2023-03-13
        • 1970-01-01
        • 2020-12-09
        • 2018-05-28
        • 2021-09-12
        相关资源
        最近更新 更多