Files
java-cui-em-oop/doc/Day01_オブジェクト指向の基本.md

16 KiB
Raw Permalink Blame History

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クラスをそのまま作成し、インスタンスを作って値を出力してみましょう。

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クラス)を作りました。

今日書いたコードは消さずに残しておいてください。次回以降のミッションで、アクセス修飾子・コンストラクタ・継承・コレクション・例外処理・ファイル入出力などを習いながら、今日作ったクラスを少しずつバージョンアップし、最終的に本物の「社員メンテナンス(ファイルシステム版)」システムに近づけていきます。