クラス・インスタンス・継承 (6/6)
作成:2013-08-10 10:50
更新:2013-08-10 10:50
更新:2013-08-10 10:50
■overrideとnewの違い
オーバーライドを理解するとき、わかりにくいのが「overrideとnewはどこが違うのか?」でしょう。
overrideは、メソッドを上書きするものです。つまり、基本クラスのメソッドは上書きされ消えてしまう(?)わけです。これに対しnewは、基本クラスのメソッドとは別のものとして新たにメソッドが追加されるため、基本クラス側のメソッドも残っています。
これは、普通に使っている分には違いをほとんど意識することはないでしょう。明確に差が現れるのは、「派生クラスのインスタンスを基本クラス型の変数に収めた場合」です。すなわち、派生インスタンスを基本クラスにキャストして利用する場合です。
下に簡単な例を挙げておきます。下の例では、EnchancedMyObjectインスタンスを作成し、MyObject変数に代入しています。
ところが、EnchancedMyObjectのprintDataにある「new」を「override」に書き替えて実行すると、結果は違ってきます。どちらもEnchancedMyObjectのprintDataが実行されるのです。overrideは、基本クラスのメソッドを上書きするため、new EnchancedMyObjectされたインスタンス内には派生クラスのメソッドしかありません。このためどのクラスにキャストしようが関係なく、EnchancedMyObjectのprintDataが実行されるのです。
このようにoverrideとnewは、「基本クラス側のメソッドを上書きするか残すか」という違いがあるため、基本クラスにキャストしたときの挙動が違います。ちょっとわかりにくいですが、両者の違いはしっかり理解しておきたいですね。
overrideは、メソッドを上書きするものです。つまり、基本クラスのメソッドは上書きされ消えてしまう(?)わけです。これに対しnewは、基本クラスのメソッドとは別のものとして新たにメソッドが追加されるため、基本クラス側のメソッドも残っています。
これは、普通に使っている分には違いをほとんど意識することはないでしょう。明確に差が現れるのは、「派生クラスのインスタンスを基本クラス型の変数に収めた場合」です。すなわち、派生インスタンスを基本クラスにキャストして利用する場合です。
下に簡単な例を挙げておきます。下の例では、EnchancedMyObjectインスタンスを作成し、MyObject変数に代入しています。
MyObject obj = new EnchancedMyObject();これですね。これでprintDataを実行すると、MyObjectにあるprintDataが実行されます。派生クラスのprintDataはnewになっているため、新しいメソッドとして追加されます。すなわち、基本クラスのprintDataもちゃんと残っているのです。このため、基本クラスにキャストすると、そちらのメソッドが実行されたのですね。そして、
EnchancedMyObject obj2 = (EnchancedMyObject)obj;こんな具合に、派生クラスにキャストしてからprintDataを呼び出せば、今度はEnchancedMyObjectに用意されたprintDataが実行されます。どちらにキャストするかによって、呼び出されるメソッドが変わるわけです。
ところが、EnchancedMyObjectのprintDataにある「new」を「override」に書き替えて実行すると、結果は違ってきます。どちらもEnchancedMyObjectのprintDataが実行されるのです。overrideは、基本クラスのメソッドを上書きするため、new EnchancedMyObjectされたインスタンス内には派生クラスのメソッドしかありません。このためどのクラスにキャストしようが関係なく、EnchancedMyObjectのprintDataが実行されるのです。
このようにoverrideとnewは、「基本クラス側のメソッドを上書きするか残すか」という違いがあるため、基本クラスにキャストしたときの挙動が違います。ちょっとわかりにくいですが、両者の違いはしっかり理解しておきたいですね。
(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); } } }
※関連コンテンツ