Unity & C# 学習教材

オーバーライドとポリモーフィズム

オーバーライドは、基底クラスで定義されたメソッドの動作を派生クラスで上書きする仕組みです。ポリモーフィズムは、基底クラス型の変数を通じてメソッドを呼んだとき、実体の型のメソッドが実行される性質です。

学習目標

前提知識


1. virtual メソッド

書式:virtual メソッドの定義

1
2
3
アクセス修飾子 virtual 戻り値の型 メソッド名(引数リスト)
{
}
要素 説明
virtual 派生クラスでオーバーライドを許可することを示すキーワード

virtual を付けたメソッドは、派生クラスで override できます。virtual を付けないメソッドはオーバーライドできません。

1
2
3
4
class A
{
    public virtual void M() { Console.WriteLine("A.M"); }
}

書式:override メソッドの定義

1
2
3
アクセス修飾子 override 戻り値の型 メソッド名(引数リスト)
{
}
要素 説明
override 基底クラスの virtual メソッドを上書きすることを示すキーワード

override するメソッドのシグネチャ(名前・戻り値型・引数の型)は基底クラスのものと一致させます。

1
2
3
4
5
6
7
8
9
class A
{
    public virtual void M() { Console.WriteLine("A.M"); }
}

class B : A
{
    public override void M() { Console.WriteLine("B.M"); }
}

3. ポリモーフィズム(動的ディスパッチ)

基底クラス型の変数に派生クラスのインスタンスを代入してメソッドを呼ぶと、実体の型のメソッドが実行されます。これを動的ディスパッチと呼びます。

1
2
3
4
5
6
7
8
9
10
11
12
class A
{
    public virtual void M() { Console.WriteLine("A.M"); }
}

class B : A
{
    public override void M() { Console.WriteLine("B.M"); }
}

A x = new B();
x.M();
1
B.M

変数の型が A であっても、実体が B であれば B.M() が呼ばれます。


よくあるミス

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
    public void M() { }     // ❌ virtual がない
}

class B : A
{
    public override void M() { }    // ❌ コンパイルエラー: A.M() はオーバーライドできない
}

// ✅ OK
class A
{
    public virtual void M() { Console.WriteLine("A.M"); }
}

class B : A
{
    public override void M() { Console.WriteLine("B.M"); }
}

まとめ


理解度チェック

  1. virtual のないメソッドを派生クラスで override しようとするとどうなりますか?
  2. 次のコードで x.M() を呼んだとき、A.M()B.M() のどちらが実行されますか?

    1
    2
    3
    4
    5
    
    class A { public virtual void M() { Console.WriteLine("A.M"); } }
    class B : A { public override void M() { Console.WriteLine("B.M"); } }
    
    A x = new B();
    x.M();
    
解答を見る
  1. コンパイルエラーになります。virtual のないメソッドはオーバーライドできません。
  2. B.M() が実行されます。変数の型は A ですが実体が B なので、動的ディスパッチによって B.M() が呼ばれます。

次のステップ

メソッドの隠ぺいと sealed では、new 修飾子による隠ぺいと sealed による拡張の制限を学びます。