virtual、new、overrideのまとめ

今まであまり深く考えてなかったので、ちょっと整理。クラスを継承する場合、同名、同引数の関数を置き換えることが出来る。置き換えにはnewもしきはoverrideキーワードを使用する。

【newキーワード】
スーパークラスに実装している関数を隠しサブクラスに新しい関数を作成する。
隠しているだけなので、スーパークラスの関数として呼び出した場合、スーパークラス側の関数を使用する。スーパークラス側の関数はvirtual指定していても、していなくても同じである。

using System;

namespace Sample1 {
    class SuperClass {
        public void SampleFunction() {
            Console.WriteLine("これはスーパークラス");
        }
    }

    class SubClass : SuperClass {
        public new void SampleFunction() {
            Console.WriteLine("これはサブクラス");
        }
    }

    class Sample1 {
        [STAThread]
        static void Main(string[] args) {
            SuperClass super = new SuperClass();
            SubClass sub = new SubClass();
            SuperClass sub_super = new SubClass();

            super.SampleFunction();
            sub.SampleFunction();
            sub_super.SampleFunction()
        }
    }
}

superとsubから呼び出されるSampleFunction()はそれぞれの関数が呼び出される。sub_superから呼び出されるSampleFunction()はSuperClassのSampleFunction()が呼び出される。

これはスーパークラス
これはサブクラス
これはスーパークラス

ちなみに new を忘れた場合、警告が出るが一応コンパイルできる。多分 new を入れていると思われる。

【overrideキーワード】
newと同じく、スーパークラスに実装している関数を上書きする。
newと異なり、スーパークラスの置き換えられる関数にoverrideキーワードを指定する必要がある。
上書きされているので、スーパークラスの関数として呼び出しても、サブクラス側の関数が利用される。

using System;

namespace Sample1 {
    class SuperClass {
        public virtual void SampleFunction() {
            Console.WriteLine("これはスーパークラス");
        }
    }

    class SubClass : SuperClass {
        public override void SampleFunction() {
            Console.WriteLine("これはサブクラス");
        }
    }

    class Sample1 {
        [STAThread]
        static void Main(string[] args) {
            SuperClass super = new SuperClass();
            SubClass sub = new SubClass();
            SuperClass sub_super = new SubClass();

            super.SampleFunction();
            sub.SampleFunction();
            sub_super.SampleFunction()
        }
    }
}

superとsubから呼び出されるSampleFunction()はそれぞれの関数が呼び出される。sub_superから呼び出されるSampleFunction()はSubClassのSampleFunction()が呼び出される。

これはスーパークラス
これはサブクラス
これはサブクラス

ちなみにvirtualを指定し忘れたらエラーとなりコンパイルできない。

【virtual】
virtual関数は呼び出しされる際に解決されるので、其の分オーバーヘッド(?)があるらしい。なのでsub_superの様な呼び出しを想定していなければvirtual関数にしない方が実行速度は速くなる(らしい)。