LoginSignup
3
4

More than 5 years have passed since last update.

C#における派生と、基底クラスへのキャスト時のnewとoverrideの挙動の違い

Posted at

仕事でMicrosoft関係のものを扱うようになったので、これを機にちょいと古いMacBook ProからSurface Pro 4に買い替えたので、それにVisual Studio Communityを入れてC#で遊んでいる。

昨日、Microsoft Virtual AcademyでC#を勉強していて、どうにも動きが良くわからんと思った「派生クラスにおいて基底クラスのメソッドをnewまたはoverrideし、それらを基底クラスにキャストして呼び出したときにどういう動きをするか」についてちょっと整理してみた。

派生と継承

基底クラスを「派生」(Derive)したクラスを作成すると、基底クラスのプロパティ、メソッドが子クラスに「継承」(Inherit)される

ということらしい。

ソースコード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class BaseClass
    {
       public static void Main()
       {
            var baseClass = new BaseClass();
            var overRide = new OverrideClass();
            var newclass = new NewClass();

            baseClass.Name();
            baseClass.Bow();

            ((BaseClass) overRide).Name();
            ((BaseClass) overRide).Bow();

            ((BaseClass) newclass).Name();
            ((BaseClass) newclass).Bow();

            Console.ReadLine();    
       }

       internal virtual void Name()
       {
            Console.WriteLine("BaseClass: Name");
       }

        internal virtual void Bow()
        {
            Console.WriteLine("BaseClass: Bow");
        }
    }

    class OverrideClass: BaseClass
    {
        internal override void Name()
        {
            Console.WriteLine("OverrideClass: Name");
        }
    }

    class NewClass: BaseClass
    {
        internal new void Name()
        {
            Console.WriteLine("NewClass: Name");
        }
    }
}

出力結果

BaseClass: Name
BaseClass: Bow
OverrideClass: Name
BaseClass: Bow
BaseClass: Name
BaseClass: Bow

考察

Overrideクラスと、NewクラスをそれぞれBaseClassから派生させた。つまり、OverrideクラスとNewクラスには、それぞれName()とBow()とが継承されている。そこで、OverrideクラスではName()をOverrideし、NewクラスではName()をNewで書き換えている。

したがって、BaseClass, OverrideClass, NewClassのBow()メソッドは、すべてBaseClassのBow()が呼ばれている。面白いのは、OverrideしたほうのName()は自身を呼んでいるが、NewしたほうのName()は基本クラスを呼び出している点だ。

C#の言語仕様によると、NewとOverrideは以下のように説明されている。

New修飾子

new キーワードを宣言の修飾子として使用すると、基底クラスから継承されたメンバーを明示的に隠ぺいできます。  継承されたメンバーを隠ぺいすると、派生バージョンのメンバーで基底クラスのバージョンが置き換えられます。

Override修飾子

override メソッドは、基本クラスから継承されたメンバーの新しい実装を提供します。  

Newは隠ぺいしているだけ(→基底クラスにキャストしたときには、基底クラスのものをそのまま呼び出す)、Overrideは上書きしている(→基底クラスにキャストしたときには、自身のものを呼び出す)ということらしい。

合っているのか……。実際の動きから考察した結果だけど、基本的なところが抜けてるからちゃんと説明できない。

参考

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4