まず初めに、私はJava初心者であり、テキストなどで勉強をしたことをアウトプットするためにこの記事を書きました。
コンストラクタってなに?
クラス名と同一名称で、インスタンス生成直後に自動的に実行されるメソッドのことである。
インスタンスを生成後、以下のように初期値をセットしている。
(newで生み出されたばかりのインスタンスフィールド(nameやhp)には何も入っていないため)
public class Main {
public static void main(String[] args) {
Hero h1 = new Hero();
h1.name = "タロウ";
h1.hp = 100;
...
}
}
実際の開発現場では複数人で開発することがほとんどであるため、1人ですべての開発を行うことはまずありえない。
そのためクラスを作るにあたっては、自分以外の開発者がこのクラスを利用することも考えておかなければいけない。
そして、それぞれの開発者が正しく値に代入してくれるとも限らない。
このような場合に備えて、Javaでは 「インスタンスが生まれた直後に自動実行される処理」 を予め定義できるようになっている。
「インスタンスが生まれた直後に自動実行される処理」→これがコンストラクタである。
public class Hero {
String name;
int hp;
...
public Hero() {
thie.hp = 100;
}
}
Hero()というメソッドが追加されている。
よってこのクラスがnewされた直後に自動的に実行されるようになっている。
また、コンストラクタは私たち開発者が直接呼び出すことはできない。
しかし以下の場合は呼び出すことができる
- オーバーロードしたコンストラクタから、別のコンストラクタを呼び出せる( this(); )
- 継承した場合は子のコンストラクタ内で、親のコンストラクタを呼び出せる( super(); )
- 特に継承した場合、子クラスのコンストラクタで super(); をつけないと、親クラスの初期化が行われずに問題になることがある。必要に応じて super(); を呼ぶこと。
インスタンスの生成時にJVMによって呼び出されるものである。
JVM:Java Virtual Machine。Javaプログラムを実行するためのソフトウェア
コンストラクタの定義方法
コンストラクタと見なされる条件
- メソッド名がクラス名と完全に一致
- メソッド宣言に戻り値が記述されていない(voidもだめ)
public class クラス名 {
クラス名() {
自動的に実行する処理
}
}
例にあげたように100などの固定値を代入するだけであればフィールド宣言を int hp = 100; にすれば良い。
複雑な条件がある場合、コンストラクタを使うのがよいとされている。
複雑な条件ってなに?
コンストラクタで引数を追加情報として受け取る
public class Hero {
String name;
int hp;
...
public Hero(String name) {
thie.hp = 100;
this.name = name;
}
}
newするときに名前の初期値も指定できる。
newで引数を渡すには以下ように書く。
public class Main {
public static void main(String[] args) {
Hero h1 = new Hero("ハナコ");
...
}
}
オーバーロードにより複数定義可能
※オーバーロード:同じ名前だが引数が異なるメソッドを複数定義する
public class Hero {
String name;
int hp;
...
public Hero(String name) {
thie.hp = 100;
this.name = name;
}
// 今回追加したコンストラクタ
public Hero() {
thie.hp = 100;
this.name = "テスト";
}
}
コンストラクタをオーバーロードしたクラスを利用するには以下である。
public class Main {
public static void main(String[] args) {
Hero h1 = new Hero("ハナコ"); // h1.nameはハナコ
Hero h2 = new Hero(); // h2.nameはテスト
...
}
}
暗黙のコンストラクタ
本来、すべてのクラスは1つ以上のコンストラクタ定義を持っている必要がある。
クラスにコンストラクタ定義が1つもない場合に限って、コンパイルが「引数なし・処理内容なし」のデフォルトコンストラクタを自動的に定義される。
public class Map {
...
public Map() {
}
}
普通に書くとこうだが、
public class Map {
...
}
これでよい。