C#でオブジェクト指向プログラミングを学ぶ上で欠かせないのが「継承」と「オーバーライド」です。クラス同士の関係性を構築したり、親クラスの機能を子クラスで拡張・変更することで、柔軟で再利用性の高いコードを書くことが可能になります。この記事では、C#の継承とオーバーライドの基本概念から、実際のコード例、注意点やベストプラクティスまでを丁寧に解説します。初心者にも理解しやすい内容で構成していますので、ぜひ最後までご覧ください。
C#の継承(Inheritance)とは、あるクラス(親クラス・基底クラス)の機能を、別のクラス(子クラス・派生クラス)が引き継ぐ仕組みです。再利用性を高めたり、共通処理をまとめる際に非常に便利です。
class Animal
{
public void Eat()
{
Console.WriteLine("食べる");
}
}
class Dog : Animal
{
public void Bark()
{
Console.WriteLine("ワンワン");
}
}
この例では、Dog
クラスがAnimal
クラスを継承しており、Eat()
メソッドをそのまま使えます。
オーバーライド(Override)は、親クラスのメソッドを子クラスで再定義して振る舞いを変えることを意味します。これにより、子クラス特有の動作を実現できます。
class Animal
{
public virtual void Speak()
{
Console.WriteLine("何か話す");
}
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("ワンワン!");
}
}
このように、virtual
キーワードでオーバーライド可能にしたメソッドを、override
で上書きします。
親クラス側で、メソッドのオーバーライドを許可するために使うキーワードです。通常のメソッドには不要ですが、オーバーライド前提の設計をする場合に使います。
子クラス側で、親クラスのvirtual
またはabstract
なメソッドを上書きするときに使います。
virtual
がないメソッドはオーバーライドできません。override
する際は、シグネチャ(引数・戻り値)が一致している必要があります。sealed override
を使うことで、さらなるオーバーライドを禁止できます。以下のようなコードで、オーバーライドの効果を確認できます。
class Animal
{
public virtual void Speak()
{
Console.WriteLine("動物が鳴く");
}
}
class Cat : Animal
{
public override void Speak()
{
Console.WriteLine("ニャー");
}
}
class Program
{
static void Main()
{
Animal a = new Cat();
a.Speak(); // 出力:ニャー
}
}
この例では、Animal
型の変数a
にCat
型のインスタンスを代入していますが、Speak()
はCat
クラスのものが呼ばれます。これを「ポリモーフィズム(多態性)」と呼びます。
C#では、同じ名前のメソッドを子クラスで定義する場合、override
ではなくnew
を使うことも可能です。ただし、これはメソッドの「隠蔽」であり、オーバーライドとは意味が異なります。
class Animal
{
public void Speak()
{
Console.WriteLine("動物が鳴く");
}
}
class Bird : Animal
{
public new void Speak()
{
Console.WriteLine("チュンチュン");
}
}
この場合、Animal
型の変数で呼び出すと、親クラスのメソッドが使われます。override
との動作の違いに注意が必要です。
抽象クラス(abstract
)は、派生クラスに特定のメソッドの実装を強制するために使われます。オーバーライドの場面ではよく登場します。
abstract class Animal
{
public abstract void Speak();
}
class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("ワン!");
}
}
このように、抽象メソッドは親クラスで実装されず、すべての派生クラスでoverride
が必須となります。
virtual
とoverride
の使い分けを行うsealed
を使って意図しないオーバーライドを防ぐbase.Method()
の呼び出しも有効C#の継承とオーバーライドは、オブジェクト指向の基本でありながら非常に強力な仕組みです。正しく理解し、適切に使いこなすことで、拡張性と再利用性の高いアプリケーション設計が可能になります。実務でも頻繁に登場する考え方なので、この記事の例を参考にしながら、ぜひ自分のコードにも取り入れてみてください。