シロウの日記

開発したもの紹介していくブログ

C# オブジェクト指向編 継承① オーバーライド part2-5

こんにちは!シロウです!

今回から継承に入ります!

継承を使えるようになると,出来る事が一気に広がります!

 

継承

継承とは?

継承は,しく宣言するクラスに,既にあるクラスの機能を組み入れる事です.

 

part2-1で説明した,インスタンスの生成では,同じ構造の物を作る事しかできませんでした.

 

では,似たような構造の物を作りたい場合は?

 

例えば,人と学生で考えてみましょう.

 

人は,年齢と名前という情報(フィールド)を持っている.

学生は,人の情報に加えて,学籍番号という情報を持っている.

 

学生を一から記述して作るより,

人の情報を使って(引き継いで),学生という情報を作った方が効率いいですよね?

 

このように,既にある物から拡張して新しい物を作る

これが継承の考え方になります.

 

イメージはこんな感じです.

f:id:pokoshirou:20181015191158p:plain

 

 

 

継承関係

先ほど説明した人と学生の関係について整理していきましょう.

図に書いたように,人クラスと学生クラスで考えます.

 

人クラスは学生クラスの元の情報を持っている.

つまり,継承元であると言えます.

この時,人クラスはスーパークラス(親クラス),または基底クラス(base class)と呼ばれます

 

一方,学生クラスは人クラスから派生してできたクラスです.

人クラスが継承元なら,学生クラスは継承先になります.

この時,学生クラスはサブクラス(子クラス),または派生クラス(derived class)と呼ばれます.

 

 

 

記述方法

C#では継承は「:(コロン)」を使って記述します.

class 継承先クラス名 : 継承元クラス名
{

}

 

人クラスと学生クラスを例にすると,このように記述します.

class Student : Human
{

}

 

フィールドの情報を入れてみるとこんな感じです.

class Human
{
    public int age;
    public string name;
}

class Student : Human
{
    // ageとnameの情報を持っている.

    public int number;  // 学籍番号という情報を追加する.
}

 

実際に簡単なプログラムで動かしてみましょう.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Student shirou = new Student();
            shirou.age = 20;            // Humanクラスの情報
            shirou.name = "シロウ";     // Humanクラスの情報
            shirou.number = 5000;

            shirou.Display1();
            shirou.Display2();
        }
    }

    class Human
    {
        public int age;
        public string name;

        // 表示
        public void Display1()
        {
            Console.WriteLine("年齢:" + this.age);
            Console.WriteLine("名前:" + this.name);
        }
    }

    class Student : Human
    {
        // ageとnameの情報を持っている.

        public int number;  // 学籍番号という情報を追加する.
        
        // 表示
        public void Display2()
        {
            Console.WriteLine("学籍番号:" + this.number);
        }
    }
}

 

実行結果

f:id:pokoshirou:20181015194917p:plain

 

Humanクラス,Studentクラスの両方の情報を持っている事が確認できます.

 

 

 

オーバーライド

先ほど使ったプログラムでは,表示する為のメソッドに,Display1とDisplay2を記述しました.

しかし,同じような機能をもつメソッドを2つも記述するのは,手間であり,今回の場合,新しく追加した情報を表示させる為だけにメソッドを新たに作成しています.

 

1つにまとめた方がいいですよね?

 

これを解消するのがオーバーライドです.

 

オーバーライドは,スーパークラス(継承元)が持つメソッドを,サブクラス(継承先)で同じメソッド名を宣言する事です.

 

オーバーライドをした場合,スーパークラスのメソッドの命令文を,サブクラスで新たに記述する命令文で上書きする事ができます.

 

オーバーライドは,override キーワードを使います.

override 型名 メソッド名(仮引数名){

}

メソッドの宣言にoverrideが付いただけです.

当たり前ですが,サブクラスでしか宣言できません

 

また,オーバーライドの元になるスーパークラスのメソッドは,virtual キーワードを先頭に付ける必要があります.

virtual 型名 メソッド名(仮引数名){

}

 

言葉だとイメージを掴みにくいと思うので,実際に記述してみます.

 

ソースコード

using System;

namespace Training
{
    class Program
    {
        static void Main(string[] args)
        {
            Student shirou = new Student();
            shirou.age = 20;            // Humanクラスの情報
            shirou.name = "シロウ";     // Humanクラスの情報
            shirou.number = 5000;

            shirou.Display();           // Studentクラスの方のDisplayメソッド.
        }
    }

    class Human
    {
        public int age;
        public string name;

        // 表示
        public virtual void Display()
        {
            Console.WriteLine("年齢:" + this.age);
            Console.WriteLine("名前:" + this.name);
        }
    }

    class Student : Human
    {
        // ageとnameの情報を持っている.

        public int number;  // 学籍番号という情報を追加する.
        
        // 表示 オーバーライド
        public override void Display()
        {
            Console.WriteLine("年齢:" + this.age);
            Console.WriteLine("名前:" + this.name);
            Console.WriteLine("学籍番号:" + this.number);
        }
    }
}

 

実行結果

f:id:pokoshirou:20181015194917p:plain

 

StudentクラスでオーバライドしたDisplayメソッドが呼び出されている事が確認できると思います.

 

オーバーライドは,上書きするイメージで考えればいいと思います!

 

 

 

今回はここまで.

次回は,継承関係とコンストラクタ,ポリモーフィズムについて書こうと思います!