インターフェースとポリモーフィズム
抽象クラスは共通の状態や実装を持つ土台として使えます。一方、異なるクラスに「この操作を提供する」という約束だけを持たせたい場合は、インターフェースが役立ちます。
インターフェース
interface IPrintable
{
void Print();
}
class Report : IPrintable
{
public void Print()
{
Console.WriteLine("Report");
}
}
class Ticket : IPrintable
{
public void Print()
{
Console.WriteLine("Ticket");
}
}
interfaceで操作の形を定義し、クラス側で:の後ろにインターフェース名を書いて実装します。上の例では、ReportとTicketの両方がPrintを提供することを約束しています。
インターフェース名はIから始める慣習があります。インターフェースは複数実装できます。
ポリモーフィズム(多態性)
インターフェース型の変数には、そのインターフェースを実装したオブジェクトを代入できます。これにより、具体的なクラスが異なっていても、共通の操作で扱えます。
class Program
{
static void Main()
{
IPrintable[] documents =
{
new Report(),
new Ticket()
};
foreach (IPrintable document in documents)
{
document.Print();
}
}
}
このように、同じPrintの呼び出しでも、実際のオブジェクトに応じた処理が実行されます。異なる型のオブジェクトを共通の型として扱い、それぞれの実装を利用する性質を**ポリモーフィズム(多態性)**と呼びます。
抽象クラスとインターフェースの使い分け
| 観点 | 抽象クラス | インターフェース |
|---|---|---|
| 主な役割 | 共通の土台を作る | 共通の操作・機能を約束する |
| 状態やフィールド | 持てる | インスタンスフィールドは持たない |
| 通常のメソッド実装 | 持てる | 既定実装などを除き、実装を持たない宣言が基本 |
| クラスとの関係 | クラスは1つのクラスだけを継承 | 複数実装できる |
どちらを使うかは、型同士に共通の状態・実装があるのか、それとも共通の操作だけが必要なのかで判断します。