在C#中,一个类可以从另一个类和一个接口继承吗?


130

我想知道一个类是否可以从一个类和一个接口继承。下面的示例代码不起作用,但我认为它传达了我想做的事情。之所以要这样做,是因为在我公司我们制造USB,串行,以太网等设备。我正在尝试开发一个通用组件/接口,我可以使用它为所有设备编写程序,以帮助使所有应用程序的通用特性(例如连接,断开连接,获取固件)保持一致。

要添加到这个问题:如果GenericDevice在另一个项目中,我可以将IOurDevices接口放在该项目中,然后如果我添加对第一个项目的引用,则使USBDevice类实现该接口吗?因为只想引用一个项目,然后根据设备是什么实现不同的接口。

class GenericDevice
{
   private string _connectionState;
   public connectionState
   {
      get{return _connectionState; }
      set{ _connectionState = value;}
   }
}

interface IOurDevices
{
   void connectToDevice();
   void DisconnectDevice();
   void GetFirmwareVersion();
}

class USBDevice : IOurDevices : GenericDevice
{
   //here I would define the methods in the interface
   //like this...
   void connectToDevice()
   {
       connectionState = "connected";
   }
}

//so that in my main program I can do this...

class myProgram
{
   main()
   {
      USBDevice myUSB = new USBDevice();
      myUSB.ConnectToDevice;
   }
}

5
供您将来参考,C#规范的10.1.4节精确地描述了如何声明具有多个基本类型的类。
埃里克·利珀特

@Eric Lippert:您能帮我了解一下这种情况是否正确,以后是否可以使用?
Gul Md Ershad

Answers:


244

是。尝试:

class USBDevice : GenericDevice, IOurDevice

注意:基类应该位于接口名称列表之前。

当然,您仍然需要实现接口定义的所有成员。但是,如果基类包含与接口成员匹配的成员,则基类成员可以用作接口成员的实现,并且不需要再次手动实现它。


1
是的,这有效!我为什么没想到呢!以及下面的评论。感谢您为我澄清(类不继承接口,IMPLEMENT接口)
PICyourBrain 2010年

1
@Jordan,还请注意,基类和要继承的接口列表在初始冒号后以逗号分隔(@Mehrdad的示例)。
JMD 2010年

1
扩展一点:如果您的基类实现了该接口,则派生类将自动实现该接口-即使没有USBDevice : IOurDevice。显式添加实现不会影响基类,但可以帮助重点放在接口上。
STW 2010年

1
@David,虽然您没看错,但并不是阻止@Jordan代码工作的术语。这是不正确的语法。
JMD 2010年

2
+1也是为了澄清我想问的关于Base和Interface中相同成员的问题。
Riegardt Steyn 2012年

20

不,不完全是。但是它可以从类继承并实现一个或多个接口。

在讨论这样的概念时,清晰的术语很重要。例如,在这里和印刷版中,您将看到乔恩·斯基特(Jon Skeet)的著作之一,那就是他在描述事物时总是很精确。


8
或埃里克·利珀特(Eric Lippert),其写作非常准确。
Mathias 2010年

20

与问题无关(Mehrdad的答案应该可以帮助您),我希望这不会被视为挑剔:类不继承接口,而是实现接口。

.NET不支持多重继承,因此保持术语的直通可以帮助进行通信。一个类可以从一个超类继承,并可以实现所需的任意数量的接口。


作为对Eric的评论的回应...,我与另一位开发人员讨论了接口是否通过以下声明进行“继承”,“实现”,“需要”或“自带”接口:

public interface ITwo : IOne

技术上的答案ITwo确实是IOne出于以下几个原因而继承的:

  • 接口永远都没有实现,因此争论ITwo 实现完全 IOne是错误的
  • ITwo继承IOne方法,如果MethodOne()存在,IOne则也可以从继承ITwo。ie:((ITwo)someObject).MethodOne())有效,即使ITwo没有明确包含MethodOne()
  • ...因为运行时是这样的! typeof(IOne).IsAssignableFrom(typeof(ITwo))退货true

我们最终同意接口支持真实/完全继承。接口,而不是接口继承中缺少缺少的继承功能(例如,替代,抽象/虚拟访问器等)。它仍然不能使这个概念变得简单或清晰,但是可以帮助您了解Eric的世界背后到底发生了什么:-)


3
但是,不幸的是,接口继承了其他接口。我发现不幸的是选择了这些词,但现在我们被困住了。我更喜欢将接口视为需要其他接口。也就是说,当您说“ interface IFoo:IBar”时,这意味着“还需要IFoo的实现者才能实现IBar”。
埃里克·利珀特

@Eric我同意这是一个不清楚的术语,并在不久前与一位同事进行了辩论。最后,我们决定说“ ITwo继承了IOne”。我将基于几个小原因来更新我的答案(仅因为它们在评论中并不清楚)。
STW 2010年

当然; 如果将“ A从B继承”定义为“ B的成员都是A的所有成员”,则接口从基本接口“继承”。这是一个合理的定义。但是我更喜欢将“继承”视为更严格地关于不仅仅共享未实现的抽象成员,而是关于继承实现。由于接口没有实现,因此我认为将接口视为从任何东西继承都有些不愉快。这是一个微妙而值得商point的地方。
埃里克·利珀特

我喜欢的另一个术语是“扩展”。因此,您可以阅读“ interface IFoo:IBar”以表示IFoo扩展了IBar的要求。
杰森2010年

1
@Joan:您是正确的,实现(并且不能继承)接口。Eric指出的一点是,接口可以继承其他接口-鉴于接口只是“规范”而不是实现,因此很难理解。
STW 2010年

1

我找到了问题第二部分的答案。是的,只要将该接口声明为公共接口,一个类就可以实现另一个类中的接口。


它不一定在所有情况下都是公开的。只是可访问的。例如class ContainsAll { private interface INested { /* ... */ } private class MyExample : INested { /* ... */ } }MyExample该类实现了一个嵌套的私有接口。在其他示例中,嵌套接口(和包含的类)可以是internal。这完全取决于谁需要使用它们并对其打扰。
Jeppe Stig Nielsen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.