インターフェイスは、クラスが実装すべきメンバーのシグネチャだけを宣言する型です。実装は持たず、「何ができるか」の契約(contract)を表します。
interface の宣言と実装の書き方を理解できるinterface の宣言書式:インターフェイスの宣言
1
2
3
4
interface インターフェイス名
{
戻り値の型 メソッド名(引数リスト);
}
| 要素 | 説明 |
|---|---|
interface |
インターフェイスを定義するキーワード |
インターフェイス名 |
慣習として I から始める(例: IFoo) |
| メンバー宣言 | シグネチャのみ。本体は書かない |
インターフェイスは「宣言するだけ」で処理の内容は書きません。処理の内容は実装するクラスが定義します。これがインターフェイスを「契約」と呼ぶ理由です。
1
2
3
4
interface IFoo
{
void M();
}
書式:インターフェイスの実装
1
2
3
4
5
6
class クラス名 : インターフェイス名
{
public 戻り値の型 メソッド名(引数リスト)
{
}
}
インターフェイスを実装するクラスは、すべてのメンバーを public で定義する必要があります。
1
2
3
4
5
6
7
8
9
interface IFoo
{
void M();
}
class A : IFoo
{
public void M() { Console.WriteLine("A.M"); }
}
インターフェイスのメンバーを実装せずにクラスを定義するとコンパイルエラーになります。
1
2
3
4
// ❌ コンパイルエラー: IFoo.M() が実装されていない
class A : IFoo
{
}
インターフェイス型の変数には、そのインターフェイスを実装したクラスのインスタンスを代入できます。変数を通じて呼ぶと、実体のクラスのメソッドが実行されます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface IFoo
{
void M();
}
class A : IFoo
{
public void M() { Console.WriteLine("A.M"); }
}
class B : IFoo
{
public void M() { Console.WriteLine("B.M"); }
}
IFoo x = new A();
x.M();
x = new B();
x.M();
1
2
A.M
B.M
C# のクラスは継承できる基底クラスが 1 つだけですが、インターフェイスは複数実装できます。
書式:複数のインターフェイスの実装
1
2
3
class クラス名 : インターフェイス名1, インターフェイス名2
{
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface IFoo
{
void M();
}
interface IBar
{
void N();
}
class A : IFoo, IBar
{
public void M() { Console.WriteLine("A.M"); }
public void N() { Console.WriteLine("A.N"); }
}
基底クラスとインターフェイスを組み合わせることもできます。その場合は基底クラスを先に書きます。
1
2
3
4
5
6
7
class Base { }
class A : Base, IFoo, IBar
{
public void M() { Console.WriteLine("A.M"); }
public void N() { Console.WriteLine("A.N"); }
}
| 項目 | 抽象クラス | インターフェイス |
|---|---|---|
| フィールド | 持てる | 持てない |
| コンストラクタ | 持てる | 持てない |
| 実装の共有 | 非抽象メソッドで共有できる | 基本的に持たない(C# 8 以降の default 実装を除く) |
| 継承・実装数 | クラスごとに 1 つのみ | 複数可 |
new でのインスタンス化 |
不可 | 不可 |
抽象クラスは「状態と実装を共有する基底」、インターフェイスは「クラス間の共通の操作を宣言する契約」と位置づけられます。
インターフェイス名を I から始める(例: IDisposable、IEnumerable)のは C# の慣習です。見た目だけでインターフェイスと分かるため、コードの読みやすさに貢献します。
class A : IFoo の形でインターフェイスを実装するpublic で定義する必要があるインターフェイスの明示的実装 では、異なるインターフェイスに同名メンバーがある場合の実装方法を学びます。