1日目のゴール
1日目のテーマは
「コンストラクタって何?」「初期化って何してるの?」を“ふわっと”から“ハッキリ”に変えること です。
今日はまだ「書き方を全部覚える日」じゃなくて、
コンストラクタ=そのクラスが「生まれる瞬間に呼ばれる特別なメソッド」
初期化=「生まれた直後の状態を整えること」
この2つのイメージを、頭の中にしっかり作る日です。
そもそも「初期化」って何?
何もしてない変数は“ゴミ状態”だと思っていい
まずは、クラスの前に「変数」で考えてみます。
int x;
System.out.println(x); // これはコンパイルエラー
Javaローカル変数(メソッドの中の変数)は、
値を入れる前に使おうとするとエラーになります。
「まだこの変数には意味のある値が入ってないよ」
「ちゃんと最初の値を決めてから使ってね」
ということです。
この「最初の値を決める」が、まさに 初期化 です。
int x = 10; // 初期化
System.out.println(x); // OK
Javaここでやっているのは、
「x という箱を用意して、最初の中身を 10 にする」
ということです。
クラスにも「初期化」が必要になる
フィールドも“最初の状態”を決めてあげないと気持ち悪い
クラスを使うときも、同じことが起きます。
public class Player {
String name;
int hp;
}
Javaこのクラスを使ってみます。
public class Main {
public static void main(String[] args) {
Player p = new Player();
System.out.println(p.name); // null
System.out.println(p.hp); // 0
}
}
JavaJava のルールで、フィールドには「デフォルト値」が入ります。
参照型(String など)は null
int は 0
boolean は false
なので、エラーにはなりません。
でも、「名前が null のプレイヤー」「HP が 0 のプレイヤー」って、
ゲームとしてはちょっと変ですよね。
本当はこうしたいはずです。
プレイヤーを作るときに、名前を決めたい
HP も、最初から 100 とかにしておきたい
この「生まれた瞬間に、ちゃんとした状態にしておく」が、
クラスにおける 初期化 です。
コンストラクタは「生まれた瞬間に呼ばれる特別メソッド」
new した瞬間に、自動で呼ばれる
ここで登場するのが コンストラクタ です。
public class Player {
String name;
int hp;
Player(String name) {
this.name = name;
this.hp = 100;
}
}
Javaこれを使うときは、こう書きます。
public class Main {
public static void main(String[] args) {
Player p = new Player("勇者");
System.out.println(p.name); // 勇者
System.out.println(p.hp); // 100
}
}
Javaここで起きていることを、ゆっくり追ってみます。
new Player("勇者") と書いた瞬間に、
Player クラスの Player(String name) が自動で呼ばれます。
その中で、
this.name = name; で、フィールドの name に「勇者」が入るthis.hp = 100; で、hp に 100 が入る
つまり、
「new した瞬間に、そのクラスの“最初の状態”をセットする場所」
それがコンストラクタです。
コンストラクタの“3つの特徴”
1. クラス名と同じ名前
public class Player {
Player(String name) { ... }
}
Javaメソッド名がクラス名と同じです。
ここが普通のメソッドとの大きな違いです。
2. 戻り値を書かない
普通のメソッドはこうですよね。
int add(int a, int b) {
return a + b;
}
Javaでもコンストラクタは、戻り値を書きません。
Player(String name) {
...
}
Javavoid すら書きません。
「戻り値を書かない=コンストラクタ」と覚えてOKです。
3. new とセットで使われる
コンストラクタは、必ず new とセットで呼ばれます。
Player p = new Player("勇者");
Javanew Player("勇者") の部分で、
コンストラクタが呼ばれて、
「ちゃんと初期化された Player オブジェクト」が返ってきます。
コンストラクタがないとどうなる?
Java が“何もしないコンストラクタ”を勝手に用意してくれる
こんなクラスを書いたとします。
public class Player {
String name;
int hp;
}
Javaコンストラクタを書いていません。
でも、これは普通に使えます。
Player p = new Player(); // これでOK
Javaなぜかというと、
コンストラクタを1つも書かなかった場合、Java が「引数なし・中身なし」のコンストラクタを自動で作ってくれる からです。
イメージとしては、こういうのが裏である感じです。
Player() {
// 何もしない
}
Javaだからこそ、さっきのように「name は null、hp は 0」の Player が生まれてしまうわけです。
「コンストラクタで初期化する」と「後から代入する」の違い
悪くはないけど“弱い”書き方
コンストラクタを使わずに、後から代入することもできます。
public class Main {
public static void main(String[] args) {
Player p = new Player();
p.name = "勇者";
p.hp = 100;
}
}
Java動きます。
でも、問題があります。
名前を入れ忘れてもコンパイルエラーにならない
hp を設定し忘れても、そのまま 0 で動いてしまう
つまり、
「正しく初期化されていない Player が簡単に生まれてしまう」
という状態です。
コンストラクタを使うと、こうなります。
Player p = new Player("勇者");
Javaこの書き方だと、
名前を渡さないとコンパイルエラーになる
「名前なしの Player」は絶対に作れない
という「強いルール」を作れます。
これが、
「初期化をコンストラクタに集める」ことの大きなメリット です。
1日目のミニアプリ:シンプルな Player 初期化
仕様を言葉で決める
Player クラスを作る
Player は名前と HP を持つ
Player を new した瞬間に、名前と HP をセットする
main で Player を1人作って、状態を表示する
コードはこうなります。
public class Player {
String name;
int hp;
Player(String name) {
this.name = name;
this.hp = 100;
}
void showStatus() {
System.out.println("名前: " + name);
System.out.println("HP : " + hp);
}
}
Javapublic class Main {
public static void main(String[] args) {
Player p = new Player("勇者");
p.showStatus();
}
}
Java実行結果のイメージはこうです。
名前: 勇者
HP : 100
ここで感じてほしいのは、
new Player("勇者") と書いた瞬間に、
「名前が勇者で、HP が 100 の Player」が必ず生まれる
という安心感です。
今日いちばん大事な“頭の中のイメージ”
コンストラクタ=「生まれた瞬間に状態を整える場所」
1日目で絶対に持って帰ってほしいのは、このイメージです。
変数の初期化
「箱を用意して、最初の中身を決めること」
クラスの初期化
「オブジェクトを new した瞬間に、その中身(フィールド)をちゃんとした状態にすること」
コンストラクタ
「new された瞬間に自動で呼ばれる、“初期化専用の特別メソッド”」
「このクラスは、こういう状態で生まれてきてほしい」という“ルールを書く場所”
そして、
コンストラクタを使うと、「正しく初期化されていないオブジェクト」が生まれにくくなる
後からバラバラに代入するより、「生まれた瞬間に全部セットする」ほうが安全で読みやすい
この感覚が入っていれば、
2日目以降の「コンストラクタのオーバーロード」「他のクラスとの組み合わせ」が、
一気に理解しやすくなります。
今日はここまでで十分。
「コンストラクタ=初期化のための特別メソッド」という一本の線が、
自分の中でつながっていれば、1日目は大成功です。


