C# はオブジェクト指向言語であり、コードの再利用性や拡張性を高める仕組みとして「継承」と「オーバーライド」が用意されています。継承を使うと既存のクラスを基に新しいクラスを作ることができ、オーバーライドを使うと親クラスのメソッドを子クラスで上書きして振る舞いを変更できます。本記事ではその基本を解説します。
継承の基本
C# では :
を使ってクラスを継承します。親クラス(基底クラス)のメンバーを子クラス(派生クラス)が引き継ぎ、追加や拡張が可能です。
class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine($"{Name} は食事中です");
}
}
class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} が吠えました:ワンワン!");
}
}
class Program
{
static void Main()
{
Dog dog = new Dog();
dog.Name = "ポチ";
dog.Eat(); // 親クラスのメソッド
dog.Bark(); // 子クラス独自のメソッド
}
}
オーバーライドの基本
親クラスで定義したメソッドを子クラスで上書きしたいときは「オーバーライド」を使います。親クラスのメソッドを virtual
で定義し、子クラス側で override
を付けて再定義します。
class Animal
{
public string Name { get; set; }
public virtual void Speak()
{
Console.WriteLine("動物が鳴きます");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} が吠えます:ワンワン!");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine($"{Name} が鳴きます:ニャー!");
}
}
class Program
{
static void Main()
{
Animal a1 = new Dog { Name = "ポチ" };
Animal a2 = new Cat { Name = "タマ" };
a1.Speak(); // ポチ が吠えます:ワンワン!
a2.Speak(); // タマ が鳴きます:ニャー!
}
}
このように、同じ Speak()
を呼び出しても、実際の型(Dog か Cat)に応じた処理が実行されます。これが「ポリモーフィズム(多態性)」です。
baseキーワードで親クラスの処理を呼ぶ
子クラスでオーバーライドする際に、親クラスの処理も利用したいときは base
キーワードを使います。
class Animal
{
public virtual void Speak()
{
Console.WriteLine("動物が音を出します");
}
}
class Bird : Animal
{
public override void Speak()
{
base.Speak(); // 親の処理を呼び出す
Console.WriteLine("鳥がさえずります:ピヨピヨ!");
}
}
sealedでオーバーライドを禁止する
継承チェーンの中で「これ以上オーバーライドさせたくない」ときは sealed
を使います。
class Animal
{
public virtual void Speak() { }
}
class Dog : Animal
{
public sealed override void Speak()
{
Console.WriteLine("ワンワン!");
}
}
// class MyDog : Dog
// {
// public override void Speak() { } // コンパイルエラー
// }
まとめ
C# の継承とオーバーライドのポイントを整理すると以下のようになります。
:
を使ってクラスを継承できるvirtual
メソッドは子クラスでオーバーライド可能override
で親クラスの処理を上書きするbase
で親クラスのメソッドを呼び出せるsealed
を使うとオーバーライドを禁止できる
継承とオーバーライドを理解すると、コードの再利用性が高まり、拡張性のある設計ができるようになります。