Java | 1 日 90 分 × 7 日アプリ学習 初級編:コンストラクタ入門アプリ

Web APP Java
スポンサーリンク

3日目のゴール

3日目のテーマは
「コンストラクタで“ただ値を入れる”から、“ちゃんと意味のある状態を作る”にレベルアップすること」 です。

1〜2日目であなたはすでに、

コンストラクタ=new された瞬間に呼ばれる特別メソッド
初期化=「生まれた直後の状態を整えること」
コンストラクタを複数用意して“生まれ方のパターン”を表現できる

というところまで来ています。

3日目ではここから一歩進んで、

「とりあえず代入」ではなく「意味のある初期状態」を設計する
「変な値が入らないようにする」初期化を考える
「他のクラスと組み合わせて初期化する」イメージを持つ

ここを、少し“アプリっぽい”例で固めていきます。


今日の題材:ユーザー登録ミニアプリで考える

「ユーザー」という現実の存在をクラスにする

現実のアプリをイメージしてみます。

ユーザーがいる
ユーザーには名前や年齢がある
ユーザー登録のときに「おかしな値」は弾きたい

これを Java のクラスにすると、まずはこうなります。

public class User {
    String name;
    int age;
}
Java

そして、こう使えます。

public class Main {
    public static void main(String[] args) {
        User u = new User();
        u.name = "太郎";
        u.age = 20;
    }
}
Java

動きます。
でも、ここには問題が潜んでいます。


「変な状態のオブジェクト」が簡単に生まれてしまう

ありえないユーザーが作れてしまう

さっきの User は、こういうこともできます。

User u1 = new User();
u1.name = null;
u1.age = -5;

User u2 = new User();
// name も age も設定しないまま使う
Java

現実世界で考えると、

名前が null のユーザー
年齢がマイナスのユーザー
名前も年齢も決まっていないユーザー

どれも「ありえない状態」ですよね。

でも、コンパイルエラーにはなりません。
つまり、

「変な状態の User が簡単に生まれてしまう」

ということです。

3日目でやりたいのは、
この「変な状態」をコンストラクタで防ぐ、という発想です。


コンストラクタで「ありえない状態」を防ぐ

必須情報をコンストラクタで受け取る

まずは、名前と年齢を必須にします。

public class User {
    String name;
    int age;

    User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    void show() {
        System.out.println("名前: " + name + ", 年齢: " + age);
    }
}
Java

使い方はこうなります。

public class Main {
    public static void main(String[] args) {
        User u = new User("太郎", 20);
        u.show();
    }
}
Java

ここで起きていることはシンプルです。

new User(“太郎”, 20) と書かないと、User は作れない
「名前なし」「年齢なし」の User はコンパイルエラーになる

これだけでも、かなり“変な状態”を防げます。

でも、まだ足りません。
年齢にマイナスを渡すことはできてしまいます。

User u = new User("太郎", -5);  // コンパイルは通る
Java

ここを、もう一段ちゃんと考えます。


コンストラクタの中で「値のチェック」をする

初期化のときに“おかしな値”を弾く

User のコンストラクタを、こう変えてみます。

public class User {
    String name;
    int age;

    User(String name, int age) {
        if (name == null || name.isEmpty()) {
            System.out.println("名前が空です。'不明' にします。");
            this.name = "不明";
        } else {
            this.name = name;
        }

        if (age < 0) {
            System.out.println("年齢がマイナスです。0 にします。");
            this.age = 0;
        } else {
            this.age = age;
        }
    }

    void show() {
        System.out.println("名前: " + name + ", 年齢: " + age);
    }
}
Java

これを使ってみます。

public class Main {
    public static void main(String[] args) {
        User u1 = new User("太郎", 20);
        User u2 = new User("", -5);

        u1.show();
        u2.show();
    }
}
Java

実行イメージはこんな感じです。

名前が空です。'不明' にします。
年齢がマイナスです。0 にします。
名前: 太郎, 年齢: 20
名前: 不明, 年齢: 0

ここでの本質は、

「コンストラクタの中で、値のチェックと補正をしている」

ということです。

これにより、

User を new した瞬間に、
「少なくともおかしすぎる状態ではない」ことが保証されます。


「初期化=ただ代入」ではない

ルールを埋め込む場所でもある

ここまでの User を見てみると、
コンストラクタは単なる「代入の場所」ではなくなっています。

名前が null や空文字なら「不明」にする
年齢がマイナスなら 0 にする

という「アプリとしてのルール」が、
コンストラクタの中に書かれています。

つまり、

初期化=「このクラスのオブジェクトは、こういうルールで生まれてくる」ことを決める作業

と言えます。

2日目までは「値をセットする」イメージが強かったと思いますが、
3日目ではそこに「ルール」という視点を足してほしいんです。


他のクラスと“まとめて初期化”するイメージ

例:プロフィールを持つユーザー

もう一歩だけ進めてみます。
User が「プロフィール情報」を持つようにしてみましょう。

プロフィールには、自己紹介文があるとします。

public class Profile {
    String bio;

    Profile(String bio) {
        if (bio == null || bio.isEmpty()) {
            this.bio = "よろしくお願いします。";
        } else {
            this.bio = bio;
        }
    }

    void show() {
        System.out.println("自己紹介: " + bio);
    }
}
Java

User に Profile を持たせます。

public class User {
    String name;
    int age;
    Profile profile;

    User(String name, int age, String bio) {
        if (name == null || name.isEmpty()) {
            System.out.println("名前が空です。'不明' にします。");
            this.name = "不明";
        } else {
            this.name = name;
        }

        if (age < 0) {
            System.out.println("年齢がマイナスです。0 にします。");
            this.age = 0;
        } else {
            this.age = age;
        }

        this.profile = new Profile(bio);
    }

    void show() {
        System.out.println("名前: " + name + ", 年齢: " + age);
        profile.show();
    }
}
Java

使い方はこうです。

public class Main {
    public static void main(String[] args) {
        User u1 = new User("太郎", 20, "Java 勉強中です!");
        User u2 = new User("", -5, "");

        u1.show();
        System.out.println("-----");
        u2.show();
    }
}
Java

ここで起きていることを整理します。

User のコンストラクタの中で、Profile も new している
User を new した瞬間に、「プロフィール付きの User」が完成する
Profile の中でも、自己紹介文のチェックと補正をしている

つまり、

「User を new するだけで、User と Profile の両方が“意味のある状態”で初期化される」

という状態になっています。

これが、「他のクラスと組み合わせて初期化する」イメージです。


初期化を“途中で止めない”という感覚

「new したら、もう使える状態」が理想

3日目で一番大事にしてほしいのは、この感覚です。

new User(...) と書いた瞬間に、
その User は「すぐに使っていい状態」になっているべき

ということです。

逆に、こういうコードが出てきたら要注意です。

User u = new User();
// ここから先で、いろいろ設定しないと使えない
u.name = "太郎";
u.age = 20;
// どこかで profile を new し忘れるかもしれない
Java

これは、

「初期化がバラバラに散らばっていて、途中で止まる可能性がある」

状態です。

コンストラクタに初期化を集める、
コンストラクタの中で値のチェックや補正をする、
必要なら他のクラスも一緒に new する——

こうすることで、

「new した瞬間に、もう安心して使える」

オブジェクトになります。


3日目のミニアプリ完成形

コードをまとめて眺めてみる

User と Profile を使った、3日目の形をもう一度まとめます。

public class Profile {
    String bio;

    Profile(String bio) {
        if (bio == null || bio.isEmpty()) {
            this.bio = "よろしくお願いします。";
        } else {
            this.bio = bio;
        }
    }

    void show() {
        System.out.println("自己紹介: " + bio);
    }
}
Java
public class User {
    String name;
    int age;
    Profile profile;

    User(String name, int age, String bio) {
        if (name == null || name.isEmpty()) {
            System.out.println("名前が空です。'不明' にします。");
            this.name = "不明";
        } else {
            this.name = name;
        }

        if (age < 0) {
            System.out.println("年齢がマイナスです。0 にします。");
            this.age = 0;
        } else {
            this.age = age;
        }

        this.profile = new Profile(bio);
    }

    void show() {
        System.out.println("名前: " + name + ", 年齢: " + age);
        profile.show();
    }
}
Java
public class Main {
    public static void main(String[] args) {
        User u1 = new User("太郎", 20, "Java 勉強中です!");
        User u2 = new User("", -5, "");

        u1.show();
        System.out.println("-----");
        u2.show();
    }
}
Java

このコードを見て、
「new した瞬間に、どんな状態のオブジェクトが生まれるか」を
自分の言葉で説明できたら、3日目はバッチリです。


3日目で絶対に押さえてほしい本質

今日いちばん大事なのは、
「初期化=ただ代入すること」ではなく、
“意味のある状態を保証すること”だと理解できたかどうか
です。

コンストラクタでやるべきことは、

必須の情報を必ず受け取るようにする
おかしな値が来たら、そこでチェックして補正する
必要な他のオブジェクトも一緒に new しておく

そして、

new した瞬間に、もう安心して使える状態にしておく

この感覚が入っていれば、
コンストラクタはもう「文法」ではなく「設計の道具」になります。

4日目以降は、
この初期化の考え方を、もっと大きなクラス構成や、
設定クラス・ゲームのステータス・アプリの設定などに広げていくと、
一気に「現場で通用するコンストラクタの使い方」に近づいていきます。

タイトルとURLをコピーしました