C#のコンストラクタの継承

コンストラクタとは、インスタンスが生成された時に自動的に最初に呼び出されるメソッドです。

つまり、クラスが new された時に実行されるメソッドです。

 

生成するクラスが継承されたクラスだった場合、親クラスと子クラスのコンストラクタはそれぞれどのように実行されていくのでしょうか?確認してみたいと思います。

コンストラクタの基本とオーバーロード

まずはコンストラクタとオーバーロードについて理解しておく必要があります。

コンストラクタとオーバーロードについては「C#のコンストラクタでオーバーロード」を参照してください。

通常は親クラスのコンストラクタがまず呼ばれる

なにも意識せずに継承クラスを作成した場合、クラスのインスタンスを生成すると、まず親クラスのコンストラクタが呼び出され、その後子クラスのコンストラクタが呼び出されるという動作になります。

 

以下の例では、TestAクラスを継承したTestBクラスがあり、さらにTestBクラスを継承したTestCクラスがあります。

    public class TestA
    {
        public TestA()
        {
            Console.Write("TestA()\n");
        }
    }

    public class TestB : TestA
    {
        public TestB()
        {
            Console.Write("TestB()\n");
        }
    }

    public class TestC : TestB
    {
        public TestC()
        {
            Console.Write("TestC()\n");
        }
    }

このTestCクラスのインスタンスを作成すると、

    static void Main(string[] args)
    {
        TestC testC = new TestC();
    }

結果は以下のような出力になります。

    TestA()
    TestB()
    TestC()

親→子→孫の順にコンストラクタが実行されていることが分かります。

明示的に親クラスのコンストラクタを呼ぶ

親クラスのコンストラクタが引数を持っている場合は、引数を持ったコンストラクタを呼び出す事を明示する必要があります。

    public class TestA
    {
        public TestA()
        {
            Console.Write("TestA()\n");
        }
    }

    public class TestB : TestA
    {
        public TestB()
        {
            Console.Write("TestB()\n");
        }

        public TestB(int a)
        {
            Console.Write("TestB(int a)\n");
        }
    }

    public class TestC : TestB
    {
        public TestC()
        {
            Console.Write("TestC()\n");
        }

        public TestC(int a) : base(a)
        {
            Console.Write("TestC(int a)\n");
        }
    }

29行目ではメソッド名の記述の後に「 : base(a)」と記述しています。

これは int型 の引数を一つ持つ親クラスのコンストラクタを実行する事を示しています。

 

※通常は「 : base()」が省略されていると考える事ができます。

 

このTestCを引数を指定してインスタンスを作成すると、

    static void Main(string[] args)
    {
        TestC testC = new TestC(0);
    }

結果は以下のような出力になります。

    TestA()
    TestB(int a)
    TestC(int a)

 

関連記事