Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

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全体の処理には変更を加えることなく、処理速度を上げることができます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした