あいさつ
今回はオブジェクト指向のカプセル化を使ったToDo管理アプリを作ってみました。
コンソール上でタスクの追加・表示・完了マーク・アプリの終了を実行することができます。最後の方にコード全体を記載しています。
開発環境
- JDK(Java開発環境、バージョン21)
- IntelliJ IDEA(エディタ)
- ターミナル(アプリの実行確認)
機能一覧
- タスクの追加
- タスクの一覧表示
- タスクの完了チェック
- アプリの終了
使用技術
- Java(標準ライブラリ)
- List
- ArrayList
- Scanner
- while
- switch
- if
▶ 実行方法
- Javaがインストールされていることを確認
- 以下のコマンドでコンパイル:
javac ToDoApp.java ToDo.java
java ToDoApp
手順
【クラスを作成】
1-1.パッケージを作成しprivateを使用しフィールドを入力
1-2.コンストラクタを生成
1-3.タスクを完了状態にするメソッドを入力
1-4.getterとsetterを生成
1-5.toStringを生成
【オブジェクトを作成】
2-1.パッケージを作成しimport文を入力
2-2.Scanner・ArrayListを宣言
2-3.whileを使用しメインメニューを表示
2-4.switchを使用し選択肢を入力
2-5.case1 新規タスクを追加
2-6.case2 タスク一覧を表示
2-7.case3 タスクを完了させる
2-8.case4 アプリを終了する
2-9.defaultで1~4以外の選択した場合の設定をする
クラスを作成
1-1.パッケージを作成しprivateを使用しフィールドを入力
フィールドにprivateを使用し、外部から直接アクセスできないように設定します。
タスク名の変数は『task』、タスクが完了状態か表示するためにBoolean型の『isDone』を変数で割り当てていきます。
package projava;
public class ToDo {
//フィールド(クラスの属性)
private String task; //タスク名
private boolean isDone; //タスクを完了状態か表示
1-2.コンストラクタを生成
コンストラクタを生成し、newでインスタンス化する際に初期値を設定しておく。
フィールドはprivateを使っていましたが、他のクラスから参照したいコードはpublicを使用します。
//コンストラクタ
public ToDo(String task) {
this.task = task;
this.isDone = false;
}
1-3.タスクを完了状態にするメソッドを入力
タスクを完了状態かをメソッドにtrueで設定する。
trueであればタスク完了、falseであれば未完を表します。
//タスクを完了状態にする
public void markDone() {
isDone = true;
}
1-4.getterとsetterを生成
getterでフィールドの値を取り出せるようにし、setterでフィールドの値を設定できるようにします。
//getter/setterのメソッド
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public boolean isDone() {
return isDone;
}
1-5.toStringを生成
toString() をオーバーライドして、オブジェクトの内容を文字列として表示できるようにする。今回はisDoneがtrueなら「☑」、falseなら「☐」を表示させています。その後ろにはtaskを記入し、文章の最後にくっつけます。
☑や☐は環境依存文字なので、文字化けやテストが難しくなるので業務向きではないかと思いますが、今回は遊び心を込めてこちらを採用しております。
//タスクの情報を文字列で返す
public String toString() {
return (isDone ? "☑" : "☐") + " "+ task;
}
}
オブジェクトを作成
2-1.パッケージを作成しimport文を入力
パッケージ宣言(全て小文字)をします。
次にパッケージとクラスの間にimport文を入力します。今回は『ArrayList』『List』『Scanner』を使用しています。
package projava;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
2-2.Scanner・ArrayListを宣言
ファイルと同名のクラス(今回だとToDoApp)にメインメソッドを書きます。
クラス名は単語の先頭が大文字になるように入力しましょう。
Scannerを使ってユーザーからの入力を受け取り、Listインターフェース型の変数 tasks を宣言し、ArrayListのインスタンスを代入することで、ToDoオブジェクトを格納するリストを準備しています。
public class ToDoApp {
public static void main(String[] args) {
//ユーザー入力を受けつけるためのScanner
Scanner scanner = new Scanner(System.in);
//タスクを保存するリスト
List<ToDo> tasks = new ArrayList<>();
2-3.whileを使用しメインメニューを表示
whileを使用しメイン画面を表示させます。
今回は『1. タスク追加』『2. 一覧表示』『3. 完了マーク』『4. 終了』の4種類を用意しました。ユーザーがキーボードから数字を入力することで次の工程に進みます。
//メニューを表示
while (true) {
System.out.println("\n==== To Do アプリケーション====");
System.out.println("1. タスク追加 2. 一覧表示 3. 完了マーク 4. 終了");
System.out.print("数字を入力してください: ");
int choice = scanner.nextInt();
scanner.nextLine();
2-4.switchを使用し選択肢を入力
switchを使用し、ユーザーがキーボードから数字を入力した結果を表示させます。
詳しい内容は次のステップでcaseごとに記載しています。
switch(choice) {
case 1 ://新規タスクを追加
case 2 ://タスク一覧を表示
case 3 ://タスクを完了させる
case 4 ://タスクを終了する
default ://1~4以外を選択された場合の対処
}
2-5.case1 新規タスクを追加
case1は新規タスクをユーザーに設定してもらいたいので、キーボードで入力できるようにします。
nextLine()を使用することで空白やタブ、改行を含めて1行全体の文字列を読み取ることができます。
switch(choice) {
case 1 : //新規タスクを追加
System.out.print("タスクを入力: ");
String task = scanner.nextLine();
tasks.add(new ToDo(task));
break;
2-6.case2 タスク一覧を表示
case2は先ほどユーザーに入力してもらったタスクを一覧にして表示します。
この画面でタスクを完了しているか確認することができます。
例) ☑洗濯
☐掃除機
case 2 : //タスク一覧を表示
for(int i =0; i < tasks.size(); i++) {
System.out.println(i + ": " + tasks.get(i));
}
break;
2-7.case3 タスクを完了させる
case3はタスクの完了マークをつける判定をします。
今回は四角いボックスの中にチェックが入っていれば完了を表しています。
例) ☐ → ☑
if文を使用することで、メニュー画面にない数字を入力すると『無効な番号です』と表示されるようにしました。
case 3 : //タスクを完了させる
System.out.print("完了にするタスク番号: ");
int index = scanner.nextInt();
if (index >= 0 && index < tasks.size()){
tasks.get(index).markDone();
} else{
System.out.println("無効な番号です");
}
break;
2-8.case4 アプリを終了する
case4はアプリそのものを終了させます。
case 4 : //アプリを終了する
System.out.println("終了します");
return;
2-9.defaultで1~4以外の選択した場合の設定をする
defaultを使用し~4以外を選択した場合『無効な選択です』と表示させ1~4の選択を再度表示します。
default : //1~4以外を選択された場合の対処
System.out.println("無効な選択です");
} //中かっこでswitchを閉じる
コードの全体像
わたし自身がコードの全体を見ながら、どこになにが書いてあるか確認したいタイプなので、まとめて表示させています。
クラス全体
package projava;
public class ToDo {
//フィールド(クラスの属性)
private String task; //タスク名
private boolean isDone; //タスクを完了状態か表示
//コンストラクタ(newでインスタンス化する時に呼ばれる)
public ToDo(String task) {
this.task = task;
this.isDone = false;
}
//タスクを完了状態にする
public void markDone() {
isDone = true;
}
//getter/setterのメソッド
public String getTask() {
return task;
}
public void setTask(String task) {
this.task = task;
}
public boolean isDone() {
return isDone;
}
//タスクの情報を文字列で返す
public String toString() {
return (isDone ? "☑" : "☐") + " "+ task;
}
}
オブジェクト全体
package projava;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ToDoApp {
public static void main(String[] args) {
//ユーザー入力を受けつけるためのScanner
Scanner scanner = new Scanner(System.in);
//タスクを保存するリスト
List<ToDo> tasks = new ArrayList<>();
//メニューを表示
while (true) {
System.out.println("\n==== To Do アプリケーション====");
System.out.println("1. タスク追加 2. 一覧表示 3. 完了マーク 4. 終了");
System.out.print("数字を入力してください: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch(choice) {
case 1 : //新規タスクを追加
System.out.print("タスクを入力: ");
String task = scanner.nextLine();
tasks.add(new ToDo(task));
break;
case 2 : //タスク一覧を表示
for(int i =0; i < tasks.size(); i++) {
System.out.println(i + ": " + tasks.get(i));
}
break;
case 3 : //タスクを完了させる
System.out.print("完了にするタスク番号: ");
int index = scanner.nextInt();
if (index >= 0 && index < tasks.size()){
tasks.get(index).markDone();
} else{
System.out.println("無効な番号です");
}
break;
case 4 : //タスクを終了する
System.out.println("終了します");
return;
default : //1~4以外を選択された場合の対処
System.out.println("無効な選択です");
}
}
}
}
学んだこと・つまづいた点
・オブジェクト指向のカプセル化がどんな構成でできているかが分かった
・オブジェクトに対してメソッド呼び出しをする方法を忘れていた
・ArrayListやListが曖昧だったのでもっとリストを利用したコードを練習が必要
まとめ
アクセス制限を設けることで外部から不正なアクセスを防ぐ仕組みを学ぶことができました。Scannerはけっこう使い慣れてきたと思います。
苦手な箇所が少しずつ分かってきたので、苦手な箇所を中心に勉強していきたいです。
最後まで見ていただき、ありがとうございました。
次にどんなコードにチャレンジするといいかアドバイスをいただけると嬉しいです。
参考にした記事
Javaで学ぶ!初心者向けToDoリストアプリの作り方|サイゼントアカデミー
初心者がJavaでTodo管理システムを作ってみるガイド|Qiita
修正した点
コメントでご指摘を受けたため修正いたしました。
『1-4.getterとsetterを生成』に入力していた setDone ですが 『markDone があるから setDone は不要』とご指摘をいただいたため setDone を削除しております。教えていただきありがとうございました!
これからも励んでいきます!
//タスクを完了状態にする
public void markDone() {
isDone = true;
}
public void setDone(boolean done) {
isDone = done;
}