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

Posted

技术标签:

【中文标题】在C#中,一个类可以继承另一个类和一个接口吗?【英文标题】:In C#, can a class inherit from another class and an interface? 【发布时间】:2011-01-04 18:57:55 【问题描述】:

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

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

class GenericDevice

   private string _connectionState;
   public connectionState
   
      getreturn _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;
   

【问题讨论】:

C# 规范第 10.1.4 节详细描述了如何声明具有多种基类型的类。 @Eric Lippert : 请您帮我了解一下这个案例是否正确以及将来是否可用? 【参考方案1】:

是的。试试:

class USBDevice : GenericDevice, IOurDevice

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

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

【讨论】:

是的,这行得通!我怎么没想到!和下面的cmets。谢谢你让我明白(类不继承接口,IMPLEMENT 接口) @Jordan,还请注意,基类和被继承的接口列表在初始冒号后用逗号分隔(@Mehrdad 的示例)。 稍微扩展一下:如果您的基类实现了接口,那么您的派生类会自动实现该接口——即使没有USBDevice : IOurDevice。显式添加实现不会影响基类,但有助于强调接口。 @David,虽然你没看错,但阻止@Jordan 的代码工作的并不是术语。语法不正确。 +1 还解决了我想问的关于 Base 和 Interface 中相同成员的问题。【参考方案2】:

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

在讨论此类概念时,清晰的术语很重要。例如,无论是在这里还是在印刷品中,你会看到 Jon Skeet 的作品有一个特点,那就是他描述事物的方式总是很准确。

【讨论】:

或者Eric Lippert,他的写作非常准确。【参考方案3】:

与问题无关(Mehrdad 的回答应该让你继续),我希望这不会被视为挑剔:类不继承接口,它们实现他们。

.NET 不支持多重继承,因此保持术语直截了当有助于交流。一个类可以从一个超类继承,并且可以实现任意数量的接口。


为了回应 Eric 的评论...我与另一位开发人员讨论了接口是否“继承”、“实现”、“要求”或“带来”具有如下声明的接口:

public interface ITwo : IOne

技术上的答案是,ITwo 确实继承了 IOne,原因如下:

接口从不有实现,所以认为ITwo 实现 IOne完全错误 ITwo 继承 IOne 方法,如果 MethodOne() 存在于 IOne 上,那么它也可以从 ITwo 访问。即:((ITwo)someObject).MethodOne()) 是有效的,即使ITwo 没有明确包含MethodOne() 的定义 ...因为运行时是这样说的! typeof(IOne).IsAssignableFrom(typeof(ITwo)) 返回true

我们最终同意接口支持真正/完全继承。缺少的继承特性(例如覆盖、抽象/虚拟访问器等)从接口中丢失,而不是从接口继承中丢失。它仍然没有使这个概念变得简单或清晰,但它有助于理解 Eric 的世界中真正发生的事情:-)

【讨论】:

虽然很遗憾,接口继承其他接口。我觉得这个词的选择很不幸,但我们现在被困住了。我更愿意将接口视为需要其他接口。也就是说,当您说“接口 IFoo : IBar”时,这意味着“IFoo 的实现者也需要实现 IBar”。 @Eric 我同意这是一个不清楚的术语,不久前与一位同事进行了辩论。最后我们决定说“ITwo 继承了 IOne”。我会用几个小理由更新我的答案(只是因为它们在评论中不适合)。 当然;如果您将“A 从 B 继承”定义为“B 的成员都是 A 的成员”,那么接口会从基本接口“继承”。这是一个合理的定义。但我更愿意将“继承”视为更严格地不仅仅是共享抽象的、未实现的成员,而是继承实现。由于接口没有实现,我觉得将接口视为继承自任何东西有点令人不安。这是一个微妙而有争议的观点。 我喜欢的另一个术语是“扩展”。因此,您可以阅读“interface IFoo : IBar”来表示 IFoo 扩展了 IBar 的要求。 @Joan:classes 实现(并且不能继承)接口是正确的。 Eric 的观点是 interfaces 可以继承其他接口——考虑到接口只是“规范”而不是实现,这可能有点难以理解。【参考方案4】:

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

【讨论】:

它不必在所有情况下都是公开的。刚刚访问。例如class ContainsAll private interface INested /* ... */ private class MyExample : INested /* ... */ MyExample 类实现了一个嵌套的私有接口。在其他示例中,嵌套接口(和包含类)可以是internal。这完全取决于谁需要使用它们并使用它们。

以上是关于在C#中,一个类可以继承另一个类和一个接口吗?的主要内容,如果未能解决你的问题,请参考以下文章

类和结构的区别

接口 到底有没有继承 Object 类

接口能被继承吗?

c#中public和protect可以被子类继承下去吗

java中接口可以实现多个接口吗

scala 抽象类和trait的区别