Java基礎 第10回『コンストラクタの役割と使い方について』

Java基礎 第9回ではクラスやオブジェクトの概念について勉強しました。
本記事は、「コンストラクタ」に焦点を当てたJavaのプログラミングについての解説であり、コンストラクタの役割、基本的な特性、詳細な運用方法について深く掘り下げています。

Javaの初学者から中級者まで、特にオブジェクト指向プログラミングにおけるオブジェクト生成と初期化のプロセスをより深く理解したいと考えている方にとって、本記事役立つ内容となっています。

目次

コンストラクタの役割と重要性

コンストラクタは、Javaのクラスが新しいオブジェクトを生成する際に、その初期設定を行うための特別なメソッドです。

具体的には、

  • オブジェクトのフィールド(データ)の初期化や、初期設定が必要なリソースの取得などが行われます。
  • クラスを元にオブジェクトを生成する際には必ず何らかのコンストラクタが呼び出されます。
  • そのクラスに定義されたコンストラクタがない場合はデフォルトコンストラクタが自動的に生成・呼び出しされます。


このコンストラクタの自動呼び出しにより、オブジェクトが初期状態であることが保証され、後のコードで扱いやすくなります。

コンストラクタの基本概念と定義

以下の表は、コンストラクタの基本的な特性を示しています

Java基礎 コンストラクタ

例えば、以下のDogクラスでは、引数なしのコンストラクタを定義しています

public class Dog {
    String name;
    int age;

    // コンストラクタ
    public Dog() {
        this.name = "Unknown";
        this.age = 0;
    }
}

このコンストラクタは特定の引数を取らず、Dogオブジェクトが生成される際に自動的に呼び出されます。コンストラクタ内で、フィールド「name」と「age」にそれぞれ“Unknown”0を設定しています。したがって、新たにDogオブジェクトを生成するときには、以下のように記述します。

Dog myDog = new Dog();

この一行が実行されると、新たにDogオブジェクト(ここではmyDogと名付けています)が生成され、その後すぐにコンストラクタが呼び出されてフィールドの初期化が行われます。その結果、myDogオブジェクトの「name」フィールドには「“Unknown”」、「age」フィールドには「0」が格納されます。

この状態を確認するためには、以下のように出力すれば良いです。

System.out.println(myDog.name); // "Unknown"
System.out.println(myDog.age);  // 0

上記のように、コンストラクタを用いることで、新たに生成したオブジェクトの初期状態を容易に制御することができます。

コンストラクタの詳細:引数ありのコンストラクタ

コンストラクタは、任意の数と型の引数を取ることができます。引数を取ることで、オブジェクト生成時に外部から初期値を指定し、より柔軟なオブジェクト初期化を行うことができます。

以下に、引数を持つコンストラクタの定義と使用の例を示します。

public class Dog {
    String name;
    int age;

    // 引数ありのコンストラクタ
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

ここでは、Dogクラスに引数を2つ(nameとage)持つコンストラクタを定義しています。このコンストラクタは、オブジェクト生成時に引数の値をフィールドに設定します。

そのため、オブジェクトを生成する際には、以下のように初期値を指定します

Dog myDog = new Dog("Rex", 5);

このコードが実行されると、まずDogオブジェクト(myDog)が生成され、その後でコンストラクタが引数と共に呼び出されます。
コンストラクタでは引数の値がフィールドに設定されるため、myDogオブジェクトの「name」フィールドには「“Rex”」、「age」フィールドには「5」が格納されます。

この状態を確認するためには、以下のように出力すれば良いです。

System.out.println(myDog.name); // "Rex"
System.out.println(myDog.age);  // 5

これにより、引数を持つコンストラクタを用いることで、オブジェクト生成時に外部から具体的な初期値を指定することが可能となります。

コンストラクタの詳細:コンストラクタのオーバーロード

一つのクラスに、引数の数や型が異なる複数のコンストラクタを定義することを、コンストラクタのオーバーロードといいます。

public class Dog {
    String name;
    int age;

    // デフォルトコンストラクタ
    public Dog() {
        this.name = "Unknown";
        this.age = 0;
    }

    // 引数ありのコンストラクタ
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

上記のコードでは、Dogクラスに引数の数が異なる2つのコンストラクタを定義しています。

  • 1つ目のコンストラクタは引数なし(デフォルトコンストラクタ)
  • 2つ目のコンストラクタは2つの引数「name」と「age」を取ります。

これにより、オブジェクト生成時の状況に応じて最適なコンストラクタを選択し、フィールドの初期化を行うことが可能になります。

こうしたクラスからオブジェクトを生成する場合には、使用するコンストラクタにより初期状態が異なります

Dog myDog1 = new Dog();
Dog myDog2 = new Dog("Rex", 5);
  • Dog myDog1 = new Dog();
    この行では、デフォルトコンストラクタが呼び出され、「name」と「age」がそれぞれ“Unknown”0に設定されます。
  • Dog myDog2 = new Dog(“Rex”, 5);
    この行では、引数を取るコンストラクタが呼び出され、「name」と「age」がそれぞれ“Rex”5に設定されます。

コンストラクタの詳細:デフォルトコンストラクタ

デフォルトコンストラクタとは引数を取らないコンストラクタのことを指します。クラスにコンストラクタが一つも定義されていない場合、Javaコンパイラは自動的にデフォルトコンストラクタを生成します。

任意の引数を持つコンストラクタを定義した場合、コンパイラはデフォルトコンストラクタを自動生成しません。これにより、引数なしでオブジェクトを生成する際にエラーが発生します。

以下の例では、デフォルトコンストラクタが自動生成される場合とされない場合を示しています。

public class Dog1 {
    String name;
    int age;
}

public class Dog2 {
    String name;
    int age;

    // 引数ありのコンストラクタ
    public Dog2(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

Dog1 myDog1 = new Dog1();  // 成功:デフォルトコンストラクタが自動生成される
Dog2 myDog2 = new Dog2();  // エラー:デフォルトコンストラクタが自動生成されない

この例では、Dog1クラスには明示的なコンストラクタが定義されていません。そのためJavaコンパイラは自動的にデフォルトコンストラクタを生成し、new Dog1()というコードがエラーなく動作します。

一方、Dog2クラスには引数を持つコンストラクタが定義されています。これによりJavaコンパイラはデフォルトコンストラクタを生成しないため、new Dog2()はエラーとなります。

このエラーを防ぐためには、明示的にデフォルトコンストラクタを定義する必要があります。

public class Dog2 {
    String name;
    int age;

    // 引数ありのコンストラクタ
    public Dog2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // デフォルトコンストラクタの明示的な定義
    public Dog2() {
    }
}

Dog2 myDog2 = new Dog2();  // 成功:明示的にデフォルトコンストラクタを定義した

コンストラクタの詳細:thisキーワードとコンストラクタ

コンストラクタの中でフィールドと引数の名前が同じ場合、thisキーワードを使ってフィールドと引数を区別する必要があります。thisキーワードは、現在のオブジェクト、つまりコンストラクタが作成するオブジェクトを参照します。

以下の例では、thisを使ってフィールドnameとageを設定します。

public class Dog {
    String name;
    int age;

    public Dog(String name, int age) {
        this.name = name;  // 'this.name'はフィールド、'name'は引数
        this.age = age;    // 'this.age'はフィールド、'age'は引数
    }
}

Dog myDog = new Dog("Rex", 5);

この例では、this.name」はDogクラスのフィールド「name」を参照し、「name」は引数の「name」を参照します。同様に、this.age」はフィールド「age」「age」は引数の「age」を参照します。このようにthisキーワードを使うことで、フィールドと引数の名前が同じでもそれぞれを区別して操作できます。

(Visited 166 times, 1 visits today)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社NEUGATEは、都内で企業研修や職業訓練を運営している会社です。主に、IT系の教育事業に力を入れています。
この記事は、株式会社NEUGATEの教育事業部が執筆をしています。

企業ホームページ:https://neugate.co.jp/

コメント

コメントする

目次