37
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C# virtual,overideの意味がわかる例。

Last updated at Posted at 2018-10-26

virtual,overideの意味がわかる例です。
今回はコンソール。

Baseというのが基本クラス。
Inheritが継承するクラス。
それぞれメソッドでWriteLineしてどのメソッドが呼ばれたかを表示します。

using System;

namespace OverrideTest
{
    class Base
    {
        public virtual void Test1()
        {
            Console.WriteLine("BaseのTest1が呼ばれました");
        }
        public void Test2()
        {
            Console.WriteLine("BaseのTest2が呼ばれました");
        }
    }

    class Inherit : Base
    {
        public override void Test1()
        {
            Console.WriteLine("InheritのTest1が呼ばれました");
        }

        public new void Test2()
        {
            Console.WriteLine("InheritのTest2が呼ばれました");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Base Base = new Base();
            Base.Test1();//BaseのTest1が呼ばれました
            Base.Test2();//BaseのTest2が呼ばれました
            Console.WriteLine();//見やすいように改行

            Inherit Inherit = new Inherit();
            Inherit.Test1();//InheritのTest1が呼ばれました
            Inherit.Test2();//InheritのTest2が呼ばれました
            Console.WriteLine();//見やすいように改行

            Base Test = new Inherit();//継承元のクラスには、暗黙的に型変換できる
            Test.Test1();//InheritのTest1が呼ばれました
            Test.Test2();//BaseのTest2が呼ばれました

            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
        }
    }
}

動作結果は以下のようなものになります。
testform.png

さて、少し詳しくmain処理を見ていきます。

            Base Base = new Base();
            Base.Test1();//BaseのTest1が呼ばれました
            Base.Test2();//BaseのTest2が呼ばれました
            Console.WriteLine();//見やすいように改行

            Inherit Inherit = new Inherit();
            Inherit.Test1();//InheritのTest1が呼ばれました
            Inherit.Test2();//InheritのTest2が呼ばれました
            Console.WriteLine();//見やすいように改行

ここはわかりやすいと思います。
それぞれの型のTest1およびTest2メソッドが呼ばれます。

            Base Test = new Inherit();//継承元のクラスには、暗黙的に型変換できる
            Test.Test1();//InheritのTest1が呼ばれました
            Test.Test2();//BaseのTest2が呼ばれました

問題は最後のここです。
継承すると継承元のクラスには暗黙的に型変換できます。
ここでは、Inherit型でnewして、Base型の変数(Test)に暗黙的に型変換して代入しています。
さて、TestからTest1及びTest2を呼び出すとどうなるのか。

overrideで記述している場合(Test1)は、newした時の型(Inherit)のメソッドが呼ばれます。
そうでない場合(Test2)は、保存されている型(Base)のメソッドが呼ばれます。

"override"日本語で言うと、上書きです。
Baseで定義したTest1を、Inheritクラスで上書きしていることになります。

実は、このオーバーライドの動きを理解すると、オブジェクト指向の"多態性"という考えが理解できます。

例えば行列演算です。ソフトウェアはDeepLearningを行うソフトで、Test1は逆行列を計算するメソッドだったとします。

このとき、2×2くらいの小さい行列の演算を何度も行う場合と、100×100くらいの巨大な行列の演算を行う場合では、最適なアルゴリズムは違ってきます。GPUを使うかCPUを使うかでも最適なアルゴリズムは変わってくるでしょう。

例えばBaseでは小さい行列の演算に最適化されたアルゴリズムになっていて、Inheritが大きい行列に特化したアルゴリズムだとすると、オーバーライドをするだけで、DeepLearning全体の処理には変更を加えることなく、処理速度を上げることができます。

37
30
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
37
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?