back

クラス・インスタンス・継承 (6/6)

■overrideとnewの違い

オーバーライドを理解するとき、わかりにくいのが「overridenewはどこが違うのか?」でしょう。

overrideは、メソッドを上書きするものです。つまり、基本クラスのメソッドは上書きされ消えてしまう(?)わけです。これに対しnewは、基本クラスのメソッドとは別のものとして新たにメソッドが追加されるため、基本クラス側のメソッドも残っています。

これは、普通に使っている分には違いをほとんど意識することはないでしょう。明確に差が現れるのは、「派生クラスのインスタンスを基本クラス型の変数に収めた場合」です。すなわち、派生インスタンスを基本クラスにキャストして利用する場合です。

下に簡単な例を挙げておきます。下の例では、EnchancedMyObjectインスタンスを作成し、MyObject変数に代入しています。
MyObject obj = new EnchancedMyObject();
これですね。これでprintDataを実行すると、MyObjectにあるprintDataが実行されます。派生クラスのprintDatanewになっているため、新しいメソッドとして追加されます。すなわち、基本クラスのprintDataもちゃんと残っているのです。このため、基本クラスにキャストすると、そちらのメソッドが実行されたのですね。そして、
EnchancedMyObject obj2 = (EnchancedMyObject)obj;
こんな具合に、派生クラスにキャストしてからprintDataを呼び出せば、今度はEnchancedMyObjectに用意されたprintDataが実行されます。どちらにキャストするかによって、呼び出されるメソッドが変わるわけです。

ところが、EnchancedMyObjectprintDataにある「new」を「override」に書き替えて実行すると、結果は違ってきます。どちらもEnchancedMyObjectprintDataが実行されるのです。overrideは、基本クラスのメソッドを上書きするため、new EnchancedMyObjectされたインスタンス内には派生クラスのメソッドしかありません。このためどのクラスにキャストしようが関係なく、EnchancedMyObjectprintDataが実行されるのです。

このようにoverridenewは、「基本クラス側のメソッドを上書きするか残すか」という違いがあるため、基本クラスにキャストしたときの挙動が違います。ちょっとわかりにくいですが、両者の違いはしっかり理解しておきたいですね。



(by. SYODA-Tuyano.)

※リストが表示されない場合

AddBlockなどの広告ブロックツールがONになっているとリストなどが表示されない場合があります。これらのツールをOFFにしてみてください。

using System;

namespace myapp
{
    class Program
    {
        public static void Main(string[] args)
        {
            MyObject obj = new EnchancedMyObject();
            obj.name = "つやの";
            obj.age = 123;
            obj.printData();
            EnchancedMyObject obj2 = (EnchancedMyObject)obj;
            obj2.mail = "syoda@tuyano.com";
            obj2.printData();
            Console.ReadKey(); // キーを押すまで待つ
        }
    }
    
    class MyObject
    {
        public string name = "(noname)";
        public int age = 0;
        
        public virtual void printData()
        {
            Console.WriteLine("名前:{0}, 年齢:{1}歳", name, age);
        }
    }
    
    class EnchancedMyObject : MyObject
    {
        public string mail = "(no mail)";
        
        public new void printData()// new をoverride に変更してみる
        {
            Console.WriteLine("名前:{0}\n\t年齢:{1}歳\n\tメール:{2}.", name, age, mail);
        }
    }
}




 

記事のリストに戻る



PC Site G+ mail