WisdomSoft - for your serial experiences.

コンストラクタ

オブジェクト作成式で新しいインスタンスが作られたとき、インスタンスの初期化を実行するコンストラクタが自動的に呼び出されます。

インスタンスの初期化

new 演算子でインスタンスが生成されるとき、インスタンスを初期化するための処理としてコンストラクタ(constructor)が実行されます。後述する静的コンストラクタという機能と区別するために、本稿で説明するインスタンスを初期化するコンストラクタのことを、厳密にはインスタンスコンストラクタ(Instance constructor)と呼びます。一般に、単にコンストラクタと呼んだ場合はインスタンスコンストラクタのことを指します。

インスタンスコンストラクタは、フィールドやメソッドと同じようにクラスのメンバとして以下のようなコンストラクタ宣言(constructor-declaration)を用いて記述します。

コンストラクタ宣言
コンストラクタ修飾子 コンストラクタ名(パラメータリスト) { コンストラクタ本体 }

コンストラクタは機能的ににメソッドと変わりませんが、メソッドと比較して 2 つの特徴を持ちます。1 つはコンストラクタの名前は常に宣言するクラスと同じであること。もう 1 つは戻り値を持たないことです。なぜコンストラクタに戻り値が無いのかというと、コンストラクタが呼び出されるのは new 演算子でインスタンスが生成されるときであり、その結果は常に初期化が終わったインスタンスそのものになるからです。

これ以外の点では、基本的にメソッドと同じです。コンストラクタ内の処理で何をしようがプログラマの自由です。ただし、意味的にインスタンスの初期化に必要な処理のみを書くべきであり、それ以外のコードをコンストラクタに含めることは正しくありません。

コード1
class MagicalGirl
{
    public MagicalGirl()
    {
        System.Console.WriteLine("魔法少女、はじめました。");
    }
}

class Test
{
    public static void Main(string[] args)
    {
        new MagicalGirl();
    }
}
実行結果
コード1 実行結果

コード1の MagicalGirl クラスではコンストラクタを宣言し、new 演算子によって新しいインスタンスが生成されると自動的にコンストラクタが呼び出されるように仕組んでいます。本来であれば、コンストラクタでは生成されたインスタンスのフィールドなどを初期化するための処理を実行しますが、このサンプルではコンストラクタが呼び出されていることを確認するため文字列を出力しています。実行結果を見れば、コンストラクタが呼び出されていることが確認できます。

コンストラクタの名前は常に宣言されるクラスの名前と同じにします。よって MagicalGirl クラスのコンストラクタ名は、クラス名と同じ MagicalGirl となります。コンストラクタの戻り値は無いので、MagicalGirl() コンストラクタには戻り値型の指定が無いことにも注目してください。

コンストラクタはメソッドと同じようにパラメータを受け取ることができます。インスタンスの初期化に何らかの値が必要な場合、コンストラクタはパラメータから値を受け取り、その値を用いて初期化します。コンストラクタがパラメータを持つ場合、new 演算子によるオブジェクト作成式で引数を渡します。

コード2
class MagicalGirl
{
    public string name;
    public MagicalGirl(string initName)
    {
        name = initName;
    }
}

class Test
{
    public static void Main(string[] args)
    {
        MagicalGirl sakura = new MagicalGirl("木之本桜");
        System.Console.WriteLine(sakura.name);
    }
}
実行結果
コード2 実行結果

コード2の MagicalGirl クラスのコンストラクタは文字列型の initName パラメータを受け取ります。このため Main() メソッドのオブジェクト作成式で、コンストラクタに対して文字列を引数に渡しています。実行結果を見れば、正しく引数が渡されフィールドに保存されていることが確認できます。

作成したクラスが明示的なコンストラクタの宣言を含まない場合は、自動的に既定のコンストラクタ(Default constructor)が作成されています。既定のコンストラクタは public なアクセス修飾子でパラメータを何も受け取らず、何もしないコンストラクタです。

フィールドの初期化とコンストラクタ

初期化子を持つフィールドが宣言されているクラス内では、コンストラクタよりも先にフィールドの初期化が実行されます。したがって、インスタンスにアクセスするあらゆるコードが実行されるよりも前に、確実にフィールドは適切に初期化されています。

コード3
class MagicalGirl
{
    public string name = "匿名希望";
    public MagicalGirl()
    {
        System.Console.WriteLine(name);
    }
}

class Test
{
    public static void Main(string[] args)
    {
        new MagicalGirl();
    }
}
実行結果
コード3 実行結果

コード3の MagicalGirl クラスの name フィールドには初期化子を指定しています。コンストラクタはインスタンスが作成されたとき、他のあらゆるコードに先駆けて自分自身を初期化するために実行されますが、フィールドの初期化子はコンストラクタよりもさらに先に実行されます。したがって、実行結果からも確認できるようにコンストラクタ内のコードが実行される時点で、フィールドは初期化子で指定した値で初期化されています。