本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第1章 オブジェクト指向 · レッスン7

ポリモーフィズム(virtual / override)

ブラウザで完結

導入

クラスのメソッドを、子クラスで上書きして振る舞いを変えられます。これにより「同じSpeak()の呼び出しでも、犬なら『ワン』猫なら『ニャー』」という**多態性(ポリモーフィズム)**が実現します。

図解

flowchart TB
    CALL["animal.Speak()<br/>(同じ呼び出し)"] --> V{"実体は?"}
    V -->|Dog| D["ワン!"]
    V -->|Cat| C["ニャー!"]
    style CALL fill:#e8f5e9

サンプル

// 親型の配列に、子オブジェクトを混ぜて入れられる
Animal[] animals = { new Dog(), new Cat() };

foreach (Animal a in animals)
{
    a.Speak();   // 実体に応じて Dog/Cat の Speak が呼ばれる
}
// ワン! / ニャー!

class Animal
{
    public virtual void Speak()   // virtual: 子で上書き可能にする
    {
        Console.WriteLine("……(動物の鳴き声)");
    }
}

class Dog : Animal
{
    public override void Speak()  // override: 親のメソッドを上書き
    {
        Console.WriteLine("ワン!");
    }
}

class Cat : Animal
{
    public override void Speak()
    {
        Console.WriteLine("ニャー!");
    }
}
  • 親のメソッドにvirtualを付けると、子で上書きできる
  • 子はoverrideで親のメソッドを上書きする
  • 親の型で扱っても、実体に応じた振る舞いが呼ばれる=ポリモーフィズム

演習

Shape[] shapes = { new Circle(), new Square() };
foreach (Shape s in shapes)
    s.Draw();

// TODO: Shape(Draw → "図形")を親に、Circle(Draw → "円")と Square(Draw → "四角")を
//       override で定義してください
___
  • 期待される出力: 四角(2行)
ヒント1を見る

親のDrawvirtual、子でoverrideします

ヒント2を見る

class Shape { public virtual void Draw() { Console.WriteLine("図形"); } } class Circle : Shape { public override void Draw() { Console.WriteLine("円"); } } class Square : Shape { public override void Draw() { Console.WriteLine("四角"); } }

まとめ

  • virtual(親)+override(子)でメソッドを上書きできる
  • 同じ呼び出しでも実体に応じた振る舞いになる=多態性
  • 親型でまとめて扱いつつ、個別の振る舞いを引き出せる

次回: 実装を持たない設計の骨組み「抽象クラス」です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。