抽象クラス (Abstract Class) とインターフェイス (Interface) は、オブジェクト指向プログラミングにおける 2 つの重要な概念であり、クラスの構造、動作、関係を定義するために使用され、ポリモーフィズム、コードの再利用、システム設計を実現するための重要な手段です。C# およびその他のオブジェクト指向プログラミング言語では、抽象クラスとインターフェイスの両方が重要な役割を果たします。この記事では、C#の抽象クラスと抽象インターフェイスの概念、特徴、使い方、応用について詳しく説明します。
1. 抽象クラスの概念と特徴
抽象クラスはインスタンス化できないクラスであり、他のクラスの基本クラスとして使用されます。これには、一般的なクラス構造と動作を定義するために使用される抽象メソッド、非抽象メソッド、フィールド、属性などのメンバーを含めることができますが、特定の実装はその派生クラスに任せて完了させます。C# では、抽象クラスはキーワードを使用してabstract
宣言されます。
抽象クラスの特徴:
- インスタンス化できません:抽象クラスは直接インスタンス化できず、他のクラスの基本クラスとしてのみ使用できます。
- 抽象メソッドを含めることができる:抽象クラスには、宣言のみを持ち、実際の実装を持たない抽象メソッドを含めることができます。抽象メソッドは、派生クラスに特定の動作を強制的に実装するために使用されます。
- 非抽象メソッドを含めることができる:抽象クラスには通常の非抽象メソッドを含めることもでき、これらのメソッドにはデフォルトの実装を含めることができます。
- フィールドとプロパティを含めることができる:抽象クラスには、データを保存し、インターフェイスを提供するためのフィールドとプロパティを含めることができます。
単純な抽象クラスの例を次に示します。
abstract class Shape
{
public abstract double CalculateArea(); // 抽象方法
public void Display()
{
Console.WriteLine("Displaying shape.");
}
}
上記のコードでは、 というShape
抽象クラスを定義しました。このクラスには、1 つの抽象メソッドCalculateArea
と 1 つの非抽象メソッドが含まれていますDisplay
。
2. インターフェースの概念と特徴
インターフェイスは、クラスが持つべき動作と機能を記述するためのメソッド、プロパティ、イベント、またはインデクサーのセットを定義する仕様です。クラスは 1 つ以上のインターフェイスを実装できるため、インターフェイスによって定義された仕様に従います。インターフェイスはC# でキーワードを使用してinterface
宣言されます。
インターフェースの特徴:
- メソッド、プロパティ、イベント、インデクサーのみを定義できます。インターフェイスにはメンバーの宣言のみを含めることができ、具体的な実装は含めることはできません。
- フィールドを含めることはできません:フィールドは具体的なデータ ストアであるのに対し、インターフェイスは動作を定義するだけであるため、インターフェイスにフィールドを含めることはできません。
- クラスは複数のインターフェイスを実装できます。クラスは複数のインターフェイスを同時に実装できるため、複数の異なる動作が可能になります。
- クラスはインターフェイス メンバーを実装する必要があります。クラスはインターフェイスを実装した後、インターフェイスで定義されているすべてのメンバーの実装を提供する必要があります。
簡単なインターフェイスの例を次に示します。
interface IDrawable
{
void Draw();
}
interface IResizable
{
void Resize();
}
class Circle : IDrawable, IResizable
{
public void Draw()
{
Console.WriteLine("Drawing a circle.");
}
public void Resize()
{
Console.WriteLine("Resizing a circle.");
}
}
IDrawable
上記のコードでは、2 つのインターフェイスとIResizable
、およびこれら 2 つのインターフェイスを実装するクラスを定義しますCircle
。
3. 抽象クラスとインターフェースの違いと応用シナリオ
違い
- メンバー実装:抽象クラスにはフィールド、プロパティ、メソッドなどのメンバーの実装を含めることができますが、インターフェイスには実際の実装を含まないメンバー宣言のみを含めることができます。
- 多重継承:クラスは 1 つの抽象クラスからのみ継承できますが、複数のインターフェイスを実装できます。これにより、インターフェースは多重継承動作が必要な状況で有利になります。
- コンストラクター:抽象クラスはコンストラクターを持つことができますが、インターフェイスはコンストラクターを持つことができません。
- アクセス修飾子:抽象クラスのメンバーは異なるアクセス修飾子を持つことができますが、インターフェイスのメンバーはデフォルトで に設定され
public
、他の修飾子は許可されません。 - 目的:抽象クラスは通常、基本クラスを定義し、共通の動作と属性を提供するために使用されます。インターフェイスは、複数の実装動作を定義し、クラスに特定の仕様を強制的に実装するために使用されます。
アプリケーションシナリオ
-
抽象クラスのアプリケーション シナリオ:
- 抽象クラスは、クラスの一般的な構造と動作を定義し、派生クラスにデフォルトの実装を提供する場合に使用されます。
- すべてのメソッドではなく、特定のメソッドを派生クラスに強制的に実装させたい場合は、一部のメソッドを抽象メソッドとして宣言できます。
- 抽象クラスは、基本クラスに具体的な実装を提供する必要があるが、派生クラスでこれらの実装をオーバーライドできるようにする必要がある場合に使用されます。
-
インターフェイスのアプリケーション シナリオ:
- インターフェイスは、さまざまなクラス間でポリモーフィズムを実現するために一連のメソッド、プロパティ、またはイベントを定義する必要がある場合に使用されます。
- 異なるクラスで共通の動作を実現する必要があり、これらのクラスが他のクラスを継承している場合、インターフェイスを実装することで多重継承によって引き起こされる問題を回避できます。
- クラス内に複数の無関係な関数を実装する必要がある場合、複数のインターフェイスを実装することで目的を達成できます。
4. C Sharp における抽象クラスとインターフェイスの実践
抽象クラスの実践的な応用
- テンプレート メソッド パターン:抽象クラスを使用してテンプレート メソッド パターンを実装できます。基本クラスはアルゴリズムのセットのスケルトンを定義するテンプレート メソッドを提供し、特定のステップは派生クラスによって実装されます。
abstract class Recipe
{
public void Cook()
{
PrepareIngredients();
CookIngredients();
Serve();
}
protected abstract void PrepareIngredients();
protected abstract void CookIngredients();
protected abstract void Serve();
}
この例では、Recipe
抽象クラスはテンプレート メソッド を定義しCook
、PrepareIngredients
、CookIngredients
、Serve
などのメソッドは具体的な派生クラスによって実装されます。
インターフェースの実用化
- ポリモーフィズム:インターフェイスを使用してポリモーフィズムを実現でき、異なるインターフェイスを実装するオブジェクトは、同じメソッドに対して異なる動作を行うことができます。
interface IPlayable
{
void Play();
}
interface IRecordable
{
void Record();
}
class MediaDevice : IPlayable, IRecordable
{
public void Play()
{
Console.WriteLine("Playing media.");
}
public void Record()
{
Console.WriteLine("Recording media.");
}
}
この例では、メディアを再生および記録できるように、MediaDevice
クラスはIPlayable
およびインターフェイスを実装します。IRecordable
- イベントとデリゲート:インターフェイスを使用してイベントとデリゲートのコントラクトを定義できるため、さまざまなクラスがイベントとデリゲートの処理を均一に実装できます。
interface IButton
{
event EventHandler Clicked;
void Click();
}
class Button : IButton
{
public event EventHandler Clicked;
public void Click()
{
// 触发 Clicked 事件
Clicked?.Invoke(this, EventArgs.Empty);
}
}
この例では、IButton
インターフェイスがClicked
イベントを定義し、Button
クラスがインターフェイスを実装してClick
メソッドでイベントを起動します。
5. 抽象クラスとインターフェイスの選択
抽象クラスまたはインターフェイスの使用を選択する場合は、特定の状況に応じてトレードオフを行う必要があります。一般的に:
- 共通の実装を共有する関連クラスのグループを定義したいが、特定の動作を実装するために派生クラスが必要な場合は、抽象クラスを使用できます。
- インターフェイスは、共通の動作を実装する無関係なクラスのセットを定義する場合に使用されます。
同時に、クラスは複数のインターフェイスを実装できますが、継承できるクラスは 1 つだけであるため、C# における多重継承の問題もインターフェイスを通じて回避できます。
6. まとめ
抽象クラスと抽象インターフェイスは、オブジェクト指向プログラミングにおける 2 つの重要な概念であり、クラスの構造、動作、関係を定義するために使用され、ポリモーフィズム、コードの再利用、システム設計の実現に役立ちます。抽象クラスは、共通の構造と動作を提供する、インスタンス化できないクラスを定義するために使用されます。インターフェイスは、メソッド、プロパティ、イベント、またはインデクサーの一連の仕様を定義するために使用され、動作と関数を記述するために使用されます。クラスにはそうあるべきです。C# では、抽象クラスとインターフェイスは、クラス階層の設計と実装、共通インターフェイスの定義、ポリモーフィズムの実装において重要な役割を果たします。抽象クラスとインターフェイスの概念、および C# でのそれらのアプリケーションを深く理解することで、柔軟で保守可能なオブジェクト指向プログラムをより適切に設計できるようになります。同時に、抽象クラスまたはインターフェイスの使用を選択するときは、特定のニーズと設計上の考慮事項に基づいてトレードオフを行う必要があります。