見た目がよく似た3つの言語で微妙に挙動が異なるのでまとめ。
C++の場合
#include <stdio.h> class BaseClass { public: void hoge() { printf("BaseClass::hoge\n"); } virtual void piyo() { printf("BaseClass::piyo\n"); } // 仮想関数 }; class SubClass : public BaseClass { public: void hoge() { printf("SubClass::hoge\n"); } void piyo() override { printf("SubClass::piyo\n"); } // 仮想関数のオーバーライド }; int main(void) { BaseClass base; base.hoge(); base.piyo(); SubClass sub; sub.hoge(); sub.piyo(); BaseClass *x = new SubClass(); x->hoge(); // BaseClass::hoge x->piyo(); // SubClass::piyo return 0; }
【実行結果】
BaseClass::hoge BaseClass::piyo SubClass::hoge SubClass::piyo BaseClass::hoge SubClass::piyo
override指定子は付けても付けなくても同じだが、仮想関数でない関数にoverride指定子を付けるとエラーになる。ミスを防ぐために付けた方がよい。
C#の場合
using System; class BaseClass { public void hoge() { Console.WriteLine("BaseClass.hoge"); } public virtual void piyo() { Console.WriteLine("BaseClass.piyo"); } // 仮想メソッド public virtual void fuga() { Console.WriteLine("BaseClass.fuga"); } // 仮想メソッド } class SubClass : BaseClass { public void hoge() { Console.WriteLine("SubClass.hoge"); } public override void piyo() { Console.WriteLine("SubClass.piyo"); } // overide指定子を付ける public void fuga() { Console.WriteLine("SubClass.fuga"); } // overide指定子を付けない } class Program { public static void Main(string[] args) { BaseClass baseObj = new BaseClass(); baseObj.hoge(); baseObj.piyo(); baseObj.fuga(); SubClass subObj = new SubClass(); subObj.hoge(); subObj.piyo(); subObj.fuga(); BaseClass x = new SubClass(); x.hoge(); // BaseClass.hoge x.piyo(); // SubClass.piyo x.fuga(); // BaseClass.fuga } }
【実行結果】
BaseClass.hoge BaseClass.piyo BaseClass.fuga SubClass.hoge SubClass.piyo SubClass.fuga BaseClass.hoge SubClass.piyo BaseClass.fuga
C#の場合、仮想メソッドであっても overide指定子を付けないと通常のメソッドと同じような挙動になる。これを明示的に宣言するにはoveride指定子のかわりにnew指定子を付ける。
Javaの場合
class BaseClass { public void hoge() { System.out.println("BaseClass.hoge"); } } class SubClass extends BaseClass { @Override public void hoge() { System.out.println("SubClass.hoge"); } } class Main { public static void main(String[] args) { BaseClass baseObj = new BaseClass(); baseObj.hoge(); SubClass subObj = new SubClass(); subObj.hoge(); BaseClass x = new SubClass(); x.hoge(); // SubClass.hoge } }
【実行結果】
BaseClass.hoge SubClass.hoge SubClass.hoge
Javaの場合、publicなメソッドは常に仮想メソッドとなる。@Overrideアノテーションは付けても付けなくても同じだが、オーバーライドしていない場合 (基底クラスに同名のメソッドが無いなどの場合) はエラーになる。ミスを防ぐために付けた方がよい。