C#では、クラスは別のクラスとインターフェイスから継承できますか?


130

クラスがクラスとインターフェースから継承できるかどうか知りたい。以下のサンプルコードは機能しませんが、私がやりたいことを伝えていると思います。私がこれをしたいのは、私たちの会社ではUSB、シリアル、イーサネットなどのデバイスを作っているからです。すべてのアプリケーションで共通のもの(接続、切断、ファームウェアの取得など)を同じに保つのに役立つ、すべてのデバイス用のプログラムを作成するために使用できる汎用コンポーネント/インターフェイスを開発しようとしています。

この質問に追加するには:GenericDeviceが別のプロジェクトにある場合、そのプロジェクトにIOurDevicesインターフェイスを配置してから、最初のプロジェクトへの参照を追加すると、USBDeviceクラスにインターフェイスを実装させることができますか?なぜなら、1つのプロジェクトを参照し、デバイスに応じて異なるインターフェイスを実装したいからです。

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

@Eric Lippert:このケースが正しい方法であり、将来的に利用可能になるかどうか、このケースについて理解するのを手伝っていただけませんか?
Gul Md Ershad 2016年

回答:


246

はい。試してください:

class USBDevice : GenericDevice, IOurDevice

注意:基本クラスは、インターフェース名のリストの前に置く必要があります。

もちろん、インターフェースが定義するすべてのメンバーを実装する必要があります。ただし、基本クラスにインターフェイスメンバーと一致するメンバーが含まれている場合、基本クラスメンバーはインターフェイスメンバーの実装として機能することができ、手動で再度実装する必要はありません。


1
うん、これはうまくいく!どうしてそんなこと考えなかったんだ!そして以下のコメントへ。それについて私を片づけてくれてありがとう(クラスはインターフェースを継承しない、実装インターフェース)
PICyourBrain

1
@Jordanは、基本クラスと継承されるインターフェースのリストが最初のコロンの後にカンマで区切られていることにも注意してください(@Mehrdadの例)。
JMD 2010年

1
少し拡張します。基本クラスがインターフェイスを実装している場合、派生クラスは自動的にそのインターフェイスを実装しますUSBDevice : IOurDevice。実装を明示的に追加しても基本クラスには影響しませんが、インターフェースを強調するのに役立ちます。
STW 2010年

1
@David、あなたが間違っているわけではありませんが、@ Jordanのコードが機能しなくなったのは専門用語ではありませんでした。不正な構文でした。
JMD 2010年

2
+1は、BaseとInterfaceの両方の同じメンバーに関して私が聞きたかった質問もクリアします。
Riegardt Steyn

21

いいえ、正確ではありません。しかし、それはクラスから継承して実装することができます 1つ以上のインターフェースできます。

このような概念について議論するときは、明確な用語が重要です。たとえばジョン・スキートの執筆をここで、そして印刷物でマークアウトすることの1つは、彼が物事を説明する方法が常に正確であることです。


8
または、その記述が非常に正確なEric Lippert。
Mathias

21

質問とは関係ありません(Mehrdadの回答であなたはうまくいくはずです)。これがごまかしではないことを願っています。クラスはインターフェイスを継承せず、それらを実装します。

.NETは複数継承をサポートしていないため、用語を正確に保つことでコミュニケーションに役立ちます。クラスは1つのスーパークラスから継承でき、必要なだけインターフェイスを実装できます。


エリックのコメントに応じて...インターフェイスを「継承」、「実装」、「要求」、または「一緒に」するかどうかについて、次のような宣言で別の開発者と話し合いました。

public interface ITwo : IOne

技術的な答えは、いくつかの理由でITwo継承さIOneれます:

  • インタフェースは、決してそうと主張し、実装を持っていないITwo 道具を IOneは間違いである
  • ITwoIOneメソッドを継承し、MethodOne()存在する場合IOneはからもアクセスできITwoます。すなわち:の定義が明示的に含まれ((ITwo)someObject).MethodOne())ITwoいなくても有効ですMethodOne()
  • ...ランタイムがそう言うからです! typeof(IOne).IsAssignableFrom(typeof(ITwo))戻り値true

最終的に、インターフェースが真/完全な継承をサポートすることに同意しました。欠落している継承機能(オーバーライド、抽象/仮想アクセサーなど)は、インターフェースの継承からではなく、インターフェースから欠落しています。それでも概念は単純でも明確でもありませんが、エリックの世界で実際に何が起こっているのかを理解するのに役立ちます:-)


3
残念ながら、インターフェースは他のインターフェースを継承します。その言葉の選択は残念なことに私は気づきますが、今はそれで行き詰まっています。私は、インターフェース他のインターフェースが必要であると考えることを好みます。つまり、「インターフェースIFoo:IBar」と言う場合、「IFooの実装者はIBarも実装する必要がある」という意味です。
Eric Lippert、2013年

@エリック私はそれが不明確な用語であることに同意し、しばらく前に同僚とそれについて議論しました。結局、「ITwoはIOneを継承する」と言うことにしました。いくつかの小さな理由で回答を更新します(コメントに明確に収まらないためです)。
STW 2010年

承知しました; 「AはBから継承する」を「BのメンバーはすべてAのメンバーである」という意味で定義すると、インターフェースは基本インターフェースから「継承」します。これは合理的な定義です。しかし、私は「継承」を、実装されていない抽象的なメンバーを共有することだけでなく、実装を継承することについてより厳密に考えることを好みます。インターフェースには実装がないため、インターフェースを何かから継承するものと考えるのはやや不穏です。それは微妙で議論の余地のあるポイントです。
Eric Lippert、2013年

私が好むもう1つの用語は「拡張」です。したがって、「インターフェイスIFoo:IBar」を読むと、IFooがIBarの要件を拡張することを意味します。
jasonh

1
@Joan:クラスがインターフェースを実装する(継承できない)ことは正しいです。Ericが指摘する点は、インターフェースは他のインターフェースを継承できるということです。インターフェースが実装ではなく「仕様」にすぎない場合、これをダイジェストするのは少し難しい場合があります。
STW

1

私の質問の2番目の部分に対する答えが見つかりました。はい、インターフェイスがパブリックとして宣言されている限り、クラスは別のクラスにあるインターフェイスを実装できます。


すべての場合に公開する必要はありません。ちょうどアクセス可能。たとえばclass ContainsAll { private interface INested { /* ... */ } private class MyExample : INested { /* ... */ } }MyExampleクラスはネストされたプライベートインターフェイスを実装します。他の例では、ネストされたインターフェース(およびそれを含むクラス)はになる可能性がありますinternal。それはすべて、誰がそれらを使用し、それらに悩む必要があるかによります。
Jeppe Stig Nielsen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.