コンストラクタとは

コンストラクタのメリット

コンストラクタ(constructor)は、インスタンス生成時に自動実行されるメソッドです。コンストラクタがないと、インスタンス生成の時点で、フィールド値が初期状態のままになってしまいます。そこでコンストラクタを使うと引数にフィールドに値を設定したり、共通処理を実行できます。

  • データ設定を必須にする
  • 必ず処理が実行される

コンストラクタの定義

コンストラクタはクラス内に、クラス名のメソッドを定義します。引数は定義できますが、戻り値は定義できません。

修飾子 クラス名 (型 引数) {
    //インスタンス生成時の処理
}

コンストラクタの実行

インスタンス生成でコンストラクタが実行

コンストラクタはインスタンス生成、つまりクラスをnewした時点で自動実行されます。

//クラスを「new」すると実行
new クラス名();

引数指定もできる

コンストラクタに引数がある場合は、引数指定もできます。

//引数を使ってインスタンスを生成
new クラス名(引数, ...);

コンストラクタの実装

コンストラクタの自動生成

コンストラクタを定義し、実行してみましょう。コンストラクタは手動でコーディングしてもよいですが、VSCodeの自動入力機能を使うと便利です。

ソースアクション

Character.javaのエディタ画面で右クリックし、「ソースアクション...」を選択します。

メニューから「Generate Constructors...」を選択します。

引数の設定

namejobにチェックして【OK】ボタンをクリックします。

Characterクラスにコンストラクタが自動挿入されました。

Character.java
public Character(String name, String job) {
    this.name = name;
    this.job = job;
}

コンストラクタ内でコンソール出力し、hp=50としておきます。

Character.java
public Character(String name, String job) {
    System.out.println("キャラクタ新規作成");
    this.name = name;
    this.job = job;
    this.hp = 50;
}

引数のコンパイルエラー

AppクラスでCharacterインスタンスを生成では、コンストラクタの引数がマッチしていないため、コンパイルエラーになります。

引数の修正

Character() の引数にnamejobを代入し、this.namethis.jobの部分は削除します。

App.java
// コンストラクタに name、jobを代入し、外部設定は削除
Character wizard = new Character("アリス", "wizard");

System.out.println(wizard.name);
System.out.println(wizard.job);
System.out.println(wizard.hp);
		
wizard.walk("left");
		
// コンストラクタに name、jobを代入し、外部設定は削除
Character warrior = new Character("ボブ",  "warrior");

wizard.talk(warrior, "勝負しましょう!");
		
System.out.println(warrior.hp);
wizard.attack(warrior);
System.out.println(warrior.hp);

コンストラクタの確認

App.javaを実行すると、Characterインスタンスを生成時にコンストラクタが実行されているのがわかります。

結果
キャラクタ新規作成
アリス
wizard
50
アリス move left
キャラクタ新規作成
ボブ!勝負しましょう!
50
49

初期化ブロック

初期化ブロックは、インスタンス生成より前で処理したい時に、{ } のメソッドで定義できます。

初期化ブロックの例

Characterクラスにlevelフィールドと初期化ブロックを追加し、levelフィールドの値を「1」で初期化します。

package rpg;

public class Character {

	public String name;
	public String job;
	public int hp;
	public int level;

	//初期化ブロック
	{
		System.out.println("初期化ブロック");
		level = 1;
	}
	
    ...
}

メインメソッドでlevelのコンソール表示を追加して、確認してみましょう。

App.java
package rpg;

public class App {

	public static void main(String[] args) {
		Character wizard = new Character("アリス", "wizard");

		System.out.println(wizard.name);
		System.out.println(wizard.job);
		System.out.println(wizard.hp);
        //追加
		System.out.println(wizard.level);
		...
	}

}

コンストラクタが実行される前に、初期化ブロックが実行されました。levelの値も初期化されています。

結果
初期化ブロック
キャラクタ新規作成
アリス
wizard
50
1
アリス move left
初期化ブロック
キャラクタ新規作成
ボブ!勝負しましょう!
50
49

演習

つぎのプログラムがあります。

Animal.java
package zoo;

public class Animal {

	public String type;
	public String name;
	public String crying;
	
	public Animal(String type, String name, String crying) {
		this.type = type;
		this.name = name;
		this.crying = crying;
	}

	public void walk() {
		String message = this.name + "が歩いた";
		System.out.println(message);
	}

	public void cry() {
		System.out.println(this.crying);
	}

	public void escape() {
		String message = this.name + "が逃げた";
		System.out.println(message);
	}
}

AnimalApp.java
package zoo;

public class AnimalApp {

	public static void main(String[] args) {
		Animal dog = new Animal("dog", "ポチ", "わん!");
		Animal cat = new Animal("cat", "ミケ", "にゃー!");
		Animal elephant = new Animal("elephant", "ジャンボ", "ぱおーん!");
		
		dog.cry();
		cat.escape();
		elephant.cry();
		dog.escape();
	}

}

問題1

Animalクラスの Animal(String type, String name, String crying) 部分のことを何といいますか?

  1. クラス
  2. インスタンス
  3. インスタンスメソッド
  4. コンストラクタ

問題2

AnimalApp.javaを実行した結果はどれですか?

  1. にゃー! ミケが逃げた ぱおーん! ポチが逃げた
  2. にゃー! ミケが逃げた わん! ポチが逃げた
  3. わん! ミケが逃げた ぱおーん! ジャンボが逃げた
  4. わん! ミケが逃げた ぱおーん! ポチが逃げた