【C#】オブジェクト指向の抽象メソッド(virtualとoverrideとは)

継承・抽象クラスと抽象メソッドとは

継承・抽象クラスと抽象メソッドに関しては下記の記事をご参考ください。

【C#】オブジェクト指向(継承とは)

2021.03.30

【C#】オブジェクト指向(抽象クラスと抽象メソッド)

2021.04.01

今回は、抽象メソッドのvirtualとoverrideについて解説していきます。

 

virtualとoverrideとは

virtual

ベースクラス(親クラス)内になるメソッドに「virtual」をつけると「オーバーライド(上書き)してもいいよ(でもしなくても大丈夫だよ)」という宣言になります。

この「virtual」をつけ、オーバーライドを許可したメソッドのことを「仮想メソッド」と呼びます。

// virtualをつける
public virtual void Stopping()
{
}

 

override

サブクラス(派生クラス)内にあるメソッドに「override」をつけると「オーバーライド(上書き)するよ」という宣言になります。

ベースクラスのメソッドを上書きしたい場合には、必ず「override」をつける必要があります。

// overrideをつける
public override void Stopping()
{
}

 

サンプルコード

前回の記事で使用したサンプルコードをもとに実装していきます。

【C#】オブジェクト指向(抽象クラスと抽象メソッド)

2021.04.01
using System;

namespace object_virtual_override
{
    public class Run
    {
        private string _name;

      // コンストラクタ
        public Run(string name)
        {
            _name = name;
        }

        public string Name
        {
            get { return _name; }
        }

      // 走る(抽象メソッド)
        public virtual void Running()
        {

        }

      // 止まる(抽象メソッド)
        public virtual void Stopping()
        {

        }
    }
}
using System;

namespace object_virtual_override
{
  // Runを継承
    public class Car : Run
    {
        public Car() : base("自動車")
        {

        }

      // overrideをつける
        public override void Running()
        {
            Console.WriteLine("ブーブー");
        }
    }
}
using System;

namespace object_virtual_override
{
    public class Bicycle : Run
    {
      // コンストラクタ
        public Bicycle() : base("自転車")
        {
        }

      // overrideをつける
        public override void Running()
        {
            Console.WriteLine("チャリンチャリン");
        }
    }
}
using System;

namespace object_virtual_override
{
    class Program
    {
        static void Main(string[] args)
        {
          // Carクラスのインスタンスを生成
            Car car = new Car();

          // Carクラスのインスタンスを生成
            Bicycle bicycle = new Bicycle();

            Console.Write(car.Name + ":");
            car.Running();

            Console.Write(bicycle.Name + ":");
            bicycle.Running();
        }
    }
}

実行結果:
自動車:ブーブー
自転車:チャリンチャリン

 

抽象クラス内の抽象メソッドとの違い

今回新たにベースクラス(Run.cs)に抽象メソッド(Stopping)を追加しました。

// 止まる(抽象メソッド) 
public virtual void Stopping()
{
}

しかし、サブクラス(Car.csとBicycle.cs)ではStoppingメソッドを使用していません。

これが「virtual」を使用した抽象メソッドのポイントになります。

ベースクラスで定義したものを必ずしもサブクラスで実装する必要はありません。

下記のコードは抽象クラス内で抽象メソッドを同じように記述したものになります。

using System;
namespace object_abstract
{
  // 抽象クラスを宣言
    public abstract class Run
    {
        private string _name;

      // コンストラクタ
        public Run(string name)
        {
            _name = name;
        }

        public string Name
        {
            get { return _name; }
        }

      // 走る(抽象メソッド)
        public abstract void Running(); // virtualではなくabstract
      // 止まる(抽象メソッド) 
        public abstract void Stopping(); // virtualではなくabstract
    }
}

抽象クラス内で抽象メソッドを定義した場合には、サブクラス内ですべての抽象メソッドを使用しなければコンパイラエラーになってしまいます。

 

まとめ

すべてのメソッドを実装する必要がある場合には、抽象クラス内に抽象メソッドを記述する。

すべてのメソッドを実装する必要がない場合には、「virtual」を使用する。

上記のように使い分けすると良いかと思います。

 

おすすめ・参考書籍

■C#を学習し始めた方向け
やさしいC 第3版 (「やさしい」シリーズ)

1週間でCの基礎が学べる本

確かな力が身につくC「超」入門 第2版 (Informatics&IDEA)

■C#をある程度学習した方向け
基礎からしっかり学ぶCの教科書 改訂新版 (マイクロソフト関連書)

独習C 新版

Effective C 6.0/7.0

オブジェクト指向における再利用のためのデザインパターン