Files
em-oop/Day01_オブジェクト指向の基本.md
2026-10-13 17:55:30 +09:00

351 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CUI_EM_OOP ミッション課題【1日目】オブジェクト指向の基本
## このミッションについて
このミッションは、最終的に **「社員メンテナンス(ファイルシステム版)」(CUI_EM_OOP)** という1つのシステムを完成させることを目標にした、複数回に分かれたミッション課題の**1日目**です。
日々の講義で新しく習った内容を少しずつ使いながら、CUI_EM_OOPを回答例と同じ形に近づけていきます。そのため、今日作るクラスは、まだ回答例とまったく同じ姿にはなりません。今後のミッションで、以下のような内容を習いながら、今日作ったクラスをどんどんバージョンアップしていく予定です。
* アクセス修飾子(`private`など)を使ったカプセル化
* コンストラクタ、`static`
* 継承・多態性
* コレクション(`ArrayList`など)
* 例外処理
* ファイルの読み書き
**今日はまだこれらを習っていないので、使いません。** 焦らず、今日習った範囲だけで取り組んでください。
## 今日の講義内容
* オブジェクト指向とは
* クラスの宣言
* フィールド
* メソッド(`static`は今回扱いません)
* フィールドへの代入
* メソッドの呼び出し
これまでの講義で習った、変数・条件分岐(`if`)・繰り返し(`for`・`while`)・配列・`Scanner`によるキーボード入力なども、引き続き使って構いません。
## すすめかた
1. 1段階目から順番に取り組んでください。むずかしそうに見えても、飛ばさないでください。
2. 各段階の「お題」をよく読んで、「何を作るのか」を最初に理解してから手を動かしましょう。
3. コードが書けたら、必ず実行して**「実行例」と同じ結果になるか**確認しましょう。
4. わからない言葉が出てきたら、まず自分で調べてみましょう。調べてもわからないときは、講師に質問してください。
5. コピー&ペーストではなく、自分の手で入力して理解しましょう。
## プロジェクトの作り方(例)
たとえば `Mission_Day01` という名前でプロジェクトを1つ作り、その`src`フォルダの直下に、今日作成する`.java`ファイルをすべて配置する形で問題ありません。(パッケージ分けは今回は行いません。パッケージ分けは今後のミッションで整理していきます。)
## 提出物
* 今日作成した`.java`ファイル一式
---
## 【基礎確認ゾーン】1〜3段階目
このゾーンは、CUI_EM_OOPとは直接関係のない練習問題です。今日習った「クラス」「フィールド」「メソッド」の基本がしっかり身についているかを確認しましょう。
### 1段階目(用意されたクラスを使ってみよう)
**お題**
以下の`Book`クラスをそのまま作成し、インスタンスを作って値を出力してみましょう。
```java
public class Book {
String title;
String author;
int price;
}
```
**<作成フローとポイント>**
1. `Book.java`を新規作成し、上記のコードをそのまま入力してください。
2. `BasicCheck1.java`を新規作成し、`main`メソッドを用意してください。
* `public static void main(String[] args)`は、これまでの練習問題と同じ書き方のままでOKです(`main`メソッドは特別なお約束事なので、`static`のままにしておきましょう)。
3. `Book`型の変数`book`を宣言し、`new`を使ってインスタンスを代入してください。
4. `book`の`title`に`"吾輩は猫である"`、`author`に`"夏目漱石"`、`price`に`800`を代入してください。
5. `book`の`title`、`author`、`price`を、それぞれ`System.out.println`で出力してください。
**<実行例>**
```
吾輩は猫である
夏目漱石
800
```
### 2段階目(自分でクラスを宣言してみよう)
**お題**
今度は用意されたクラスを使うのではなく、自分で「学生」を表すクラスを宣言してみましょう。
**<作成フローとポイント>**
1. `Student.java`を新規作成してください。
2. 以下のフィールドを宣言してください。
* `studentId`(`int`型)
* `name`(`String`型)
* ※アクセス修飾子(`public`や`private`)はまだ習っていないので、何もつけずに宣言してください。
3. 以下のメソッドを宣言してください。
* メソッド名:`printProfile`
* 引数:なし
* 戻り値:なし(`void`)
* 中身:`"学籍番号:" + this.studentId + " 名前:" + this.name` という内容を`System.out.println`で出力する
4. `BasicCheck2.java`を新規作成し、`main`メソッドの中で以下を行ってください。
* `Student`型の変数`student`を宣言し、インスタンスを代入する
* `student`の`studentId`に`1`、`name`に`"鈴木一郎"`を代入する
* `student`の`printProfile`メソッドを呼び出す
**<実行例>**
```
学籍番号:1 名前:鈴木一郎
```
### 3段階目(複数のインスタンスを扱ってみよう)
**お題**
お店の商品を表す`Item`クラスを作り、複数の商品を配列で管理してみましょう。「同じクラスから作ったインスタンスでも、それぞれ別々の値を持てる」ことを確認するのが今回のポイントです。
**<作成フローとポイント>**
1. `Item.java`を新規作成してください。
2. 以下のフィールドを宣言してください(アクセス修飾子はなしでOKです)。
* `name`(`String`型)
* `price`(`int`型)
* `stock`(`int`型:在庫数)
3. 以下のメソッドを宣言してください。
* メソッド名:`sell`
* 引数:`int amount`
* 戻り値:なし(`void`)
* 中身:`stock`から`amount`を引く(`this.stock = this.stock - amount;`)
4. `BasicCheck3.java`を新規作成し、`main`メソッドの中で以下を行ってください。
* `Item`型の配列`items`を3件分用意する(`Item[] items = new Item[3];`)
* `items[0]`〜`items[2]`にそれぞれ`new`でインスタンスを代入する
* 以下の値をそれぞれ設定する
| index | name | price | stock |
|---|---|---|---|
| 0 | ノート | 120 | 50 |
| 1 | 消しゴム | 80 | 30 |
| 2 | 鉛筆 | 60 | 100 |
* `for`文を使って、3件それぞれの`sell`メソッドを、引数`5`を渡して呼び出す
* `for`文を使って、3件それぞれの`name`、`price`、`stock`を出力する(出力形式は自由です)
**<実行例>**
```
ノート 120円 残り45個
消しゴム 80円 残り25個
鉛筆 60円 残り95個
```
**<余裕がある人向け(任意)>**
`Item`クラスに、戻り値のあるメソッド`totalPrice`(引数なし、戻り値`int`、`price * stock`を返す)を追加し、3商品の合計金額も計算して出力してみましょう。
---
## 【CUI_EM_OOP制作ゾーン】4〜6段階目
ここからは、いよいよ最終目標であるCUI_EM_OOPの部品を実際に作っていきます。回答例では`EmployeeData`クラスの各フィールドは`private`で守られていますが、今日はまだカプセル化を習っていないため、フィールドには修飾子をつけずに作成してください。**今日作るクラスは、今後のミッションで少しずつ回答例の形に近づけていきます。**
### 4段階目(EmployeeDataクラスの型を作ろう)
**お題**
社員1人分の情報を格納する`EmployeeData`クラスを作成しましょう。
**<作成フローとポイント>**
1. `EmployeeData.java`を新規作成してください。
2. 以下のフィールドを、すべて`String`型・修飾子なしで宣言してください。
* `idEmployee`(社員ID)
* `nmEmployee`(社員名)
* `knEmployee`(社員名カナ)
* `mailAddress`(メールアドレス)
* `password`(パスワード)
* `idDepartment`(部署ID)
* ※メソッドはまだ作りません。
3. `Main.java`を新規作成し、`main`メソッドの中で以下を行ってください。
* `EmployeeData`型の変数`employee`を宣言し、インスタンスを代入する
* 以下の値(`EmployeeData.csv`の1件目のデータです)を、各フィールドに代入する
* `idEmployee`:`"10000"`
* `nmEmployee`:`"山田龍也"`
* `knEmployee`:`"ヤマダタツヤ"`
* `mailAddress`:`"yamada@hoge.jp"`
* `password`:`"aaa"`
* `idDepartment`:`"10"`
* 6つのフィールドを、それぞれ`System.out.println`で出力する
**<実行例>**
```
10000
山田龍也
ヤマダタツヤ
yamada@hoge.jp
aaa
10
```
### 5段階目(社員情報を表示するメソッドを作ろう)
**お題**
4段階目の`EmployeeData`クラスに、自分の情報をまとめて表示するメソッドを追加しましょう。
**<作成フローとポイント>**
1. `EmployeeData.java`に、以下のメソッドを追加してください。
* メソッド名:`showInfo`
* 引数:なし
* 戻り値:なし(`void`)
* 中身:6つのフィールドの値を、タブ区切り(`"\t"`)でつなげて`System.out.println`で出力する
* 例:`this.idEmployee + "\t" + this.nmEmployee + ...`
* ※回答例ではこの処理は`toString`という特別な名前のメソッドとして作られていますが、その仕組みはまだ習っていないので、今日は`showInfo`という名前で作成します。
2. `Main.java`を修正してください。
* 4段階目で書いた「6つのフィールドをそれぞれ出力する」処理を削除し、代わりに`employee.showInfo();`を呼び出すように変更する
**<実行例>**
```
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
```
### 6段階目(複数の社員をまとめて表示してみよう)
**お題**
実際のシステムには社員が何人もいます。複数の社員データをまとめて表示できるようにしましょう。
**<作成フローとポイント>**
1. `Main.java`を修正してください。
2. `EmployeeData`型の配列`employees`を5件分用意する(`EmployeeData[] employees = new EmployeeData[5];`)
3. `employees[0]`〜`employees[4]`にそれぞれ`new`でインスタンスを代入し、以下の値(`EmployeeData.csv`の先頭5件です)を設定してください。
```
10000,山田龍也,ヤマダタツヤ,yamada@hoge.jp,aaa,10
10001,高橋準,タカハシジュン,jtaka@hoge.jp,bbb,10
10002,麻枝史明,マエダフミアキ,fmak@hoge.jp,ccc,11
10003,丸戸章介,マルトショウスケ,marusyo@hoge.jp,ddd,12
10004,三宅武,ミヤケタケシ,miya@hoge.jp,eee,13
```
4. `for`文を使って、5件すべての`showInfo`メソッドを呼び出してください。
**<実行例>**
```
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
10002 麻枝史明 マエダフミアキ fmak@hoge.jp ccc 11
10003 丸戸章介 マルトショウスケ marusyo@hoge.jp ddd 12
10004 三宅武 ミヤケタケシ miya@hoge.jp eee 13
```
> **ポイント**:これは、最終的に完成するCUI_EM_OOPの「1:検索 → 1:全検索」を選んだときの表示と、実はまったく同じ見た目になります。今日作ったものが、将来そのままシステムの一部になっていきます。
---
## 【挑戦問題ゾーン】7〜9段階目
ここからは応用問題です。今日習った内容に加えて、自分で少し調べながら進める部分があります。難しく感じても焦らず、じっくり調べながら取り組んでみましょう(経験者の方でも、多少時間がかかる内容です)。
### 7段階目(IDが一致するか調べるメソッドを作ろう)
**お題**
`EmployeeData`クラスに、指定した社員IDと自分自身の`idEmployee`が一致するかどうかを判定するメソッドを追加してください。
* メソッド名:`isMatchId`
* 引数:`String id`
* 戻り値:`boolean`(一致していれば`true`、していなければ`false`)
**<考え方のヒント>**
* 文字列(`String`)どうしが同じ値かどうかを比べるとき、`==`を使うと期待通りの結果にならないことがあります。「Java 文字列 比較」などで調べて、正しい比較方法を探してみましょう。
* `Main.java`で、6段階目の`employees`配列の中から`"10002"`というIDと`"99999"`というIDのそれぞれについて`isMatchId`を呼び出し、結果を出力して動作を確認してください。
**<実行例>**
```
10002 を検索します
true
99999 を検索します
false
```
### 8段階目(社員をID検索してみよう)
**お題**
7段階目で作った`isMatchId`メソッドを使って、実際に「IDで社員を検索する」機能を作ってみましょう。
**<お題の条件>**
* `Scanner`を使って、「検索したい社員IDを入力してください」と表示し、キーボード入力を受け取る
* 6段階目の`employees`配列を`for`文で1件ずつ確認し、入力されたIDと一致する社員を探す
* 一致する社員が見つかったら、その社員の`showInfo`メソッドを呼び出す
* 配列の最後まで確認しても見つからなかった場合は、「該当する社員が見つかりませんでした」と表示する
**<考え方のヒント>**
* 「見つかったかどうか」を覚えておくための`boolean`型の変数を1つ用意すると、作りやすくなります。
**<実行例>**
```
検索したい社員IDを入力してください
10001
10001 高橋準 タカハシジュン jtaka@hoge.jp bbb 10
```
```
検索したい社員IDを入力してください
99999
該当する社員が見つかりませんでした
```
### 9段階目(何度でも検索できるようにしよう)
**お題**
8段階目のままだと、1回検索したらプログラムが終わってしまいます。実際のシステムのように、何度でも検索できるようにしましょう。
**<お題の条件>**
* `"0"`が入力されるまで、検索を繰り返せるようにしてください
* `"0"`が入力されたら、「システムを終了します」と表示してプログラムを終了してください
**<実行例>**
```
検索したい社員IDを入力してください(終了する場合は0)
10000
10000 山田龍也 ヤマダタツヤ yamada@hoge.jp aaa 10
検索したい社員IDを入力してください(終了する場合は0)
99999
該当する社員が見つかりませんでした
検索したい社員IDを入力してください(終了する場合は0)
0
システムを終了します
```
> **ポイント**:この「`0`と入力されるまで繰り返す」という作りは、最終的な回答例の`Main.java`にある`while (true)`でメニューを繰り返す仕組みの原型です。
---
## まとめ
今日は「クラス」「フィールド」「メソッド」というオブジェクト指向の一番の基本を使って、社員データを扱う土台(`EmployeeData`クラスと`Main`クラス)を作りました。
今日書いたコードは消さずに残しておいてください。次回以降のミッションで、アクセス修飾子・コンストラクタ・継承・コレクション・例外処理・ファイル入出力などを習いながら、今日作ったクラスを少しずつバージョンアップし、最終的に本物の「社員メンテナンス(ファイルシステム版)」システムに近づけていきます。