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

Web APP Java
スポンサーリンク

7日目のゴール

7日目のテーマは
「コンストラクタと初期化を使って、“アプリ全体の最初の状態”を自分で設計しきること」 です。

ここまでであなたはすでに、

コンストラクタで必須情報を受け取る
おかしな値を補正したり、例外で拒否したりできる
関連するクラスをまとめて初期化できる
new の1行が「そのオブジェクトの自己紹介」になるように設計できる

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

7日目では、
「アプリ全体の“スタート状態”をどう作るか」 をテーマに、
小さな「タスク管理ミニアプリ」を設計していきます。


今日の題材:タスク管理ミニアプリの“最初の状態”を設計する

現実のイメージからクラスを洗い出す

タスク管理アプリをイメージしてみます。

タスクがある
タスクにはタイトル・締め切り・優先度がある
ユーザーがいる
アプリ全体の設定(通知オンオフ・1日の最大タスク数など)がある

これをクラスにすると、登場人物はこうなります。

Task … 1つのタスク
User … アプリを使う人
AppSetting … アプリ全体の設定
TaskApp … 「ユーザー+設定+タスク一覧」をまとめて持つクラス
Main … それらを new して、アプリの“最初の状態”を作る場所

7日目のゴールは、
「TaskApp を new した瞬間に、“ちゃんと使えるタスクアプリの初期状態”ができている」
という形を、自分で設計できることです。


Task クラスを“初期化の基本形”として整える

1つのタスクが「ありえない状態」にならないようにする

まずは Task から。

public class Task {
    String title;
    String deadline;   // 本当は日付型がいいけど、ここでは文字列にします
    int priority;      // 1〜3 とする(1: 高, 2: 中, 3: 低)

    Task(String title, String deadline, int priority) {
        if (title == null || title.isEmpty()) {
            throw new IllegalArgumentException("タスク名は必須です。");
        }
        if (deadline == null || deadline.isEmpty()) {
            throw new IllegalArgumentException("締め切りは必須です。");
        }
        if (priority < 1 || priority > 3) {
            System.out.println("優先度が範囲外です。3(低) にします。");
            this.priority = 3;
        } else {
            this.priority = priority;
        }

        this.title = title;
        this.deadline = deadline;
    }

    void show() {
        System.out.println("タスク: " + title + " / 締め切り: " + deadline + " / 優先度: " + priority);
    }
}
Java

ここでやっていることは、これまでの総復習です。

タイトル・締め切りは「なかったらダメ」なので例外で拒否
優先度は「範囲外なら補正」する
new した瞬間に、「少なくとも変なタスクではない」ことを保証する

Task 単体としては、これで「初期化の意味」をちゃんと満たしています。


User と AppSetting で“アプリの前提”を固める

User は「アプリを使う人」の最小単位

User はシンプルにいきます。

public class User {
    String name;

    User(String name) {
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("ユーザー名は必須です。");
        }
        this.name = name;
    }

    void show() {
        System.out.println("ユーザー: " + name);
    }
}
Java

ここも同じです。

「名前なしのユーザー」はありえないので、例外で拒否
new した瞬間に、「名前を持ったユーザー」が必ずできる

AppSetting は「アプリ全体のルール」をまとめる

次に、アプリ全体の設定です。

public class AppSetting {
    boolean notificationEnabled;
    int maxTasksPerDay;

    AppSetting(boolean notificationEnabled, int maxTasksPerDay) {
        this.notificationEnabled = notificationEnabled;

        if (maxTasksPerDay <= 0) {
            System.out.println("1日の最大タスク数が 0 以下です。10 にします。");
            this.maxTasksPerDay = 10;
        } else {
            this.maxTasksPerDay = maxTasksPerDay;
        }
    }

    void show() {
        System.out.println("通知: " + (notificationEnabled ? "ON" : "OFF"));
        System.out.println("1日の最大タスク数: " + maxTasksPerDay);
    }
}
Java

ここでのポイントは、

「通知オンオフ」「1日の最大タスク数」という“アプリのルール”を1か所に集めている
maxTasksPerDay のおかしな値は、ここで補正する
main に「0 以下なら 10 にして…」などと書かせない

ということです。


TaskApp で“アプリ全体の初期状態”を作る

「ユーザー+設定+タスク一覧」をまとめて初期化する

いよいよ今日の主役、TaskApp です。

public class TaskApp {
    User user;
    AppSetting setting;
    Task[] tasks;
    int taskCount;

    TaskApp(User user, AppSetting setting, int maxTasks) {
        if (user == null) {
            throw new IllegalArgumentException("ユーザーは必須です。");
        }
        this.user = user;

        if (setting == null) {
            System.out.println("設定が null です。デフォルト設定を使います。");
            this.setting = new AppSetting(true, 10);
        } else {
            this.setting = setting;
        }

        if (maxTasks <= 0) {
            System.out.println("maxTasks が 0 以下です。10 にします。");
            maxTasks = 10;
        }

        this.tasks = new Task[maxTasks];
        this.taskCount = 0;
    }

    boolean addTask(Task task) {
        if (task == null) {
            System.out.println("null のタスクは追加できません。");
            return false;
        }
        if (taskCount >= tasks.length) {
            System.out.println("これ以上タスクを追加できません。");
            return false;
        }
        tasks[taskCount] = task;
        taskCount++;
        return true;
    }

    void showAll() {
        System.out.println("=== タスクアプリの状態 ===");
        user.show();
        setting.show();
        System.out.println("--- タスク一覧 ---");
        if (taskCount == 0) {
            System.out.println("タスクはまだありません。");
            return;
        }
        for (int i = 0; i < taskCount; i++) {
            System.out.print((i + 1) + ". ");
            tasks[i].show();
        }
    }
}
Java

ここでやっていることを、丁寧に言葉にします。

コンストラクタで User を必須にしている
User が null なら、そもそも TaskApp を作らせない

AppSetting が null のときは、デフォルト設定を自分で用意する
「設定を渡し忘れたから落ちる」ではなく、「それならデフォルトで行く」という選択

maxTasks が 0 以下なら、10 に補正する
内部で使う配列を、ここで new しておく
taskCount を 0 にして、「まだタスクはない」という正しい初期状態にする

addTask では、「null のタスク」「容量オーバー」を防いでいる

つまり、

new TaskApp(user, setting, maxTasks) と書いた瞬間に、
「ユーザーがいて、設定があり、タスクを入れる準備ができたアプリ」が完成する

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


main から見た“アプリの初期化”を確認する

new の流れが「アプリのスタート」をそのまま表しているか?

ここまでのクラスを main から使ってみます。

public class Main {
    public static void main(String[] args) {
        User user = new User("MONO");

        AppSetting setting = new AppSetting(true, 5);

        TaskApp app = new TaskApp(user, setting, 20);

        Task t1 = new Task("Java 勉強", "2026-05-30", 1);
        Task t2 = new Task("買い物", "2026-05-25", 2);
        Task t3 = new Task("ランニング", "2026-05-24", 3);

        app.addTask(t1);
        app.addTask(t2);
        app.addTask(t3);

        app.showAll();
    }
}
Java

この main を眺めてみてください。

new User("MONO") で、「誰がこのアプリを使うか」が決まる
new AppSetting(true, 5) で、「通知オン・1日最大5タスク」というルールが決まる
new TaskApp(user, setting, 20) で、「このユーザー・この設定・最大20タスクのアプリ」がスタートする
そのあとで、Task を追加していく

この流れそのものが、
「アプリが起動して、最初の状態が整うまで」 を表しています。

ここが、7日目で一番見てほしいポイントです。


「アプリ全体の初期化」を自分の言葉で説明できるか?

7日間の学びを“1枚の絵”にする

ここまでのコードを、言葉だけで説明してみます。

アプリを起動するとき、まず「誰が使うか(User)」を決める
次に、「どんなルールで動くか(AppSetting)」を決める
その2つを渡して、「タスクを入れる箱(TaskApp)」を作る
TaskApp の中では、「タスクを入れる配列」と「タスク数」が正しく初期化される
Task を追加するときは、Task 自身も「ありえない状態」にならないようにコンストラクタで守られている

つまり、

「アプリ全体の“最初の状態”が、コンストラクタの連携で安全に作られている」

という構造になっています。

これを自分の言葉で説明できたら、
「初期化の意味」はもう完全にあなたの中に根づいています。


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

最後に、7日間の「初期化」の学びを、1本の線にまとめます。

変数の初期化
「箱を用意して、最初の中身を決めること」

クラスの初期化
「オブジェクトを new した瞬間に、その中身(フィールド)を“意味のある状態”にすること」

コンストラクタの役割
必須情報を受け取る
おかしな値を補正したり、拒否したりする
関連するオブジェクトもまとめて初期化する
new の1行が、そのオブジェクトの“自己紹介”になるようにする

そして今日の一番大事なポイントは、

「初期化=オブジェクト単体ではなく、“アプリ全体のスタート状態”を設計すること」

という視点を持てたかどうかです。

「このアプリは、どんな状態でスタートしていてほしい?」
「そのために、どのクラスのコンストラクタで、何を決めるべき?」

ここまで考えられるようになっていたら、
あなたはもう「コンストラクタを知っている人」ではなく、
“初期化を設計できるプログラマ” です。

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