【问题标题】:Why does "interface have no implementation"? - C#为什么“接口没有实现”? - C#
【发布时间】:2013-02-15 11:35:43
【问题描述】:

我一直在阅读一些与多继承和接口相关的代码理论。它在所有地方都说interface is a class without implementation

1) 没有在接口中实现方法/功能有什么用?是不是支持同一个方法在继承一个接口的不同类中多次实现?

2) 那里的大多数代码示例似乎都显示了void 接口方法。接口函数/方法总是void吗?

【问题讨论】:

  • 您应该在发布问题之前尝试搜索一下:here
  • (1) 差不多,是的。 (2) 不一定;你可以有非 void 方法、属性、事件...
  • 可能有点背景:C#没有像c那样的多重继承。在 C 中,您可能有一个带有一些方法的基类,基类的 2 个(或更多)子类,然后是从两个子类继承的“大”子类。这通常被称为“钻石问题”。孙子是否应该表现得像其中一个孩子,哪一个? java 和 c# 尝试使用“抽象”类(即接口)来避免来自这个星座的问题。您可以实现一些接口,但不能从多个类继承。
  • @Offler,我在 SO on MI 进行了一次精彩的对话 :) 感谢您的意见。作为对您评论后一部分的总结,我可以这样说Class D: A, IB, IC 吗? (IB、IC是两个不同的接口,所以这个D类继承自A类和两个接口/抽象类)
  • 如果您执行“D 类:A、IB、IC”之类的操作,则您从 A 类继承。如果 A 具有非抽象公共方法,您可以调用它们。对于 IB,您只说:D 包含在 IB 中声明但在 IB 中没有代码的方法的实现。 D 实现了充当 IB 所必需的代码。或者换句话说:你真正继承自 A,它声明并定义了可以使用的方法; IB 仅显示需要哪种结构,如果您在类中实现接口,则需要具有此名称的东西。

标签: c# interface implementation


【解决方案1】:

对于问题 1:是的,这是使用接口的原因之一。接口通常用作组件的 API。消费者可能不知道实际的实现,通过单元测试支持松散耦合和可测试性。

关于问题2:不,接口方法可以与类方法具有相同的方法签名。

【讨论】:

  • 谢谢。您能否提供后一个原因的示例:“消费者可能不知道实际的实现,通过单元测试支持松散耦合和可测试性。”
  • 松耦合主要用于依赖注入容器,如 Castle Windsor、Unity、NInject 或 Spring Framework。要了解 DI(或控制反转作为该模式的更通用名称)的一般概念,您应该查看一些教程,例如:joelabrahamsson.com/entry/…。关于可测试性:单元测试应该只测试一个单元,因此依赖(可能很多)其他组件的测试组件很难独立测试。使用模拟框架或存根可以使单元测试更容易。
  • 嗯,这超出了我的能力范围:) 我用interface inheritance 的形式查看了this tutorial,而不是在LinQ 上。然而,大多数文章都使用classes implement interfaces 而不是classes inherit from interfaces。类似于您在其中一个 cmets 中提到的内容。那么正确的标准是什么?实现还是继承?如果是这样,为什么这篇文章会说继承?
  • 接口继承是一个接口从另一个接口继承方法声明的概念。实现这样的接口与实现不继承任何方法声明的接口没有什么不同。
【解决方案2】:

1) 没有实现的方法/函数有什么用? 界面? 是否支持相同的多个实现 继承接口的不同类中的方法

是的。

2) 那里的大多数代码示例似乎都显示 void interface 方法。 接口函数/方法总是无效的吗?

没有。一点也不。它可以返回任何东西。

【讨论】:

  • 谢谢。那么在第一种情况下,我仍然可以编写一个父类并继承它的一个特定方法,并在多个子类中以不同的方式实现它。我设法做到了。那么将这些方法放在接口中的好处是什么(除了尝试使用多重继承的解决方法)? :)
  • @aspiring,你的问题应该是为什么使用接口? ,您已经在评论中提到了其中一个原因,接口实际上定义了一个合同并且对多态性很有用。你需要阅读更多关于这个概念的信息,这可能是一个好的开始cs.utah.edu/~germain/PPS/Topics/interfaces.html
  • 谢谢 :) 有帮助,所有的帮助和文章。
【解决方案3】:

对于 1) 是的,您的想法是正确的。假设,你有一个只有一些方法makeSound 的接口。现在您可以在一些Guitar 类和一些Drums 类中实现该接口。您只需要在您的程序中知道您有一些实现makeSound 的对象,因此您可以调用该方法。无需知道实际的输出/声音是什么。

对于 2) 不,接口可以包含具有任何签名的方法。

【讨论】:

  • 所以你的意思是类似于Graphics 类中的Draw() 方法?但是Guitar 必须发出吉他声音,Drums 也是如此。要说实现那个makeSound方法的时候,会走子类实现的声音吗?如果是makeShape,会变成子类吗?
  • 它将采用最合适的实现。如果您override 一个实现,那么将采用该实现。因为GuitarDrums不相互继承,所以会使用它们各自的实现。
  • @aspiring 不要将接口实现视为“子类”。该接口只是一种承诺,即实现该接口的对象将具有一个名为 X 的方法,该方法带有签名 Y。在 DaDaDoms 示例中,如果您的对象是吉他,则 Interface.makeSound 实际上是 Guitar.makeSound。如果对象是 Drums 类型,它将是 Drums.makeSound。
猜你喜欢
  • 2017-05-14
  • 1970-01-01
  • 2021-01-14
  • 2017-08-07
  • 2023-03-16
  • 2020-06-07
  • 1970-01-01
  • 2018-10-24
  • 2011-02-06
相关资源
最近更新 更多