前回記事、オブジェクト指向とは何なのかを簡単に説明してみるの練習題材です。
ここでは3つのオブジェクトを作成していきます。
– 会計オブジェクト:会計金額の算出
– 請求書オブジェクト:請求明細の保持と合計金額の算出
– 請求明細オブジェクト:請求する内容の保持
目的
オブジェクト指向プログラミングの練習。
仕様理解、フィールド、コンストラクター、メソッドの実装に慣れる。
仕様
会計クラス
・クラス名:Account
・以下のフィールドを持つ。
請求書クラス
・コンストラクターの引数は請求書クラスとする。
・以下のメソッドを持つ。
請求書クラスの合計額から消費税を算出する。
請求書クラスの合計に消費税を加算した、総請求額を算出する。。
請求書クラス
・クラス名:Invoice
・以下のフィールドを持つ。
請求先名
請求詳細クラスのリスト
・コンストラクターの引数は請求先名とする。
・以下のメソッドを持つ。
請求先名の表示
請求詳細の追加
請求額の合計算出
請求詳細クラス
・クラス名:InvoiceDetail
・以下のフィールドを持つ。
商品名
請求額
品数
・コンストラクターの引数は、商品名、請求額、品数とする。
・以下のメソッドを持つ。
商品名を取得
請求額を取得
品数を取得
Mainクラス
・クラス名:Main
・請求書オブジェクトを生成する。
・請求書オブジェクトに請求詳細のオブジェクトをいくつか追加する。
・会計オブジェクトを生成する。
・合計額を算出する。
手順
会計クラスの実装(1)
・フィールドにInviceクラスを定義する。
この時点でInvoiceクラスは無いため、空のInvoiceクラスを作成しておく。
・コンストラクターを実装します。
1 2 3 4 5 6 |
// コンストラクター Account(Invoice invoice){ this.invoice = invoice; } |
・メソッドを実装します。
– 消費税額の算出
– 総請求額の算出
税率は10%の固定値にしています。
まだInvoiceクラスから合計金額を取得できない(未実装の)ため、
固定値「0」で仮実装しておきます。
1 2 3 4 5 6 7 8 9 10 11 |
// メソッド public int tax() { double TAX_RATE = 0.1; return (int)(Math.ceil(0 * TAX_RATE)); // 金額は0で仮実装 } public int totalInvoice() { return 0 + tax(); // 金額は0で仮実装 } |
会計クラスは一旦ここまでです。
先に請求書クラスと請求詳細クラスを実装してから、再度メソッドの中身を実装します。
請求書クラスの実装(1)
・フィールドを実装します。
請求者名はStringとします。
請求詳細クラスのListを定義します。
請求詳細クラスはこの時点ではまだ、空のクラスとして作成しておきます。
1 2 3 4 5 6 |
// 請求書クラス // フィールド private String billingName; private List<InvoiceDetail> invoiceDetailList; |
1 2 3 4 5 6 |
// 請求詳細クラス public class InvoiceDetail { } |
・コンストラクターを実装します。
請求詳細クラスのフィールドは、空のListで初期化しておきます。
1 2 3 4 5 6 7 8 |
// 請求書クラス // コンストラクター Invoice(String billingName){ this.billingName = billingName; this.invoiceDetailList = new ArrayList<>(); } |
・メソッドを実装します。
請求先名はGetterです。
請求詳細の追加は、Listのaddを使います。
請求詳細の合計算出メソッドは、固定値「0」 で仮実装しておます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 請求書クラス // メソッド public String billingName() { return billingName; } public void add(InvoiceDetail invoiceDetail) { invoiceDetailList.add(invoiceDetail); } public int totalAmount() { int total = 0; for(InvoiceDetail invoice: invoiceDetailList) { total += 0 * 0; // amount * numの想定 } return total; } |
請求書クラスは一旦ここまでとします。
請求明細クラスの実装を行い、請求明細からの値が取得できるようになったら残りを実装します。
請求詳細クラスの実装
・フィールドに、商品名、請求額、請求数を定義します。
1 2 3 4 5 6 7 |
// 請求明細クラス // フィールド private String name; private int amount; private int num; |
・コンストラクターを実装します。
1 2 3 4 5 6 7 8 9 |
// 請求明細クラス // コンストラクター InvoiceDetail(String name, int amount, int num){ this.name = name; this.amount = amount; this.num = num; } |
・メソッドを実装します。
実装するのは、各フィールドのgetterです。
私は個人的に、getHoge()という「get」が好きではないため、name()というメソッド名にします。
そうすると、呼び出しの際、「invoiceDetail.name()」となり、
「請求詳細の名称」のような自然言語に近い表現になると感じているためです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 請求明細クラス // メソッド public String name() { return name; } public int amount() { return amount; } public int num() { return num; } |
請求詳細クラスはこれで完成です。
請求書クラスの実装(2)
・請求明細の合計算出メソッドを実装します。
Listで実装してるので、拡張for文が使えます。
1 2 3 4 5 6 7 8 9 10 |
// 請求書クラス public int totalAmount() { int total = 0; for(InvoiceDetail invoice: invoiceDetailList) { total += invoice.amount() * invoice.num(); } return total; } |
これで請求書クラスの実装は完了です。
会計クラスの実装(2)
– 消費税を算出
– 請求総額を算出
仮実装で「0」としていた請求金額を、「invoice.totalAmount()」に修正します。
1 2 3 4 5 6 7 8 9 10 11 12 |
// 会計クラス // メソッド public int tax() { double TAX_RATE = 0.1; return (int)(Math.ceil(invoice.totalAmount() * TAX_RATE)); } public int totalInvoice() { return invoice.totalAmount() + tax(); } |
これで会計クラスの実装は完了です。
メインクラス
以下の順で実際に合計額が表示されるか見てみましょう。
・請求書オブジェクトを生成する。
・請求書オブジェクトに請求詳細のオブジェクトをいくつか追加する。
・会計オブジェクトを生成する。
・合計額を算出する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// メインクラス public class Main { public static void main(String...strings) { // 請求書オブジェクトを生成する。 Invoice invoice = new Invoice("Yamada Taro"); // 請求書オブジェクトに請求詳細のオブジェクトをいくつか追加する。 invoice.add(new InvoiceDetail("カレーライス", 800, 1)); invoice.add(new InvoiceDetail("お子様ランチ", 450, 2)); invoice.add(new InvoiceDetail("スパゲティ", 600, 1)); // 会計オブジェクトを生成する。 Account account = new Account(invoice); // 合計額を算出する。 System.out.println(invoice.billingName() + "様のお会計合計は、" + " " + account.totalInvoice() + "円です。"); } } |
1 2 3 4 |
// 出力結果 Yamada Taro様のお会計合計は、 2530円です。 |
まとめ
・仕様に基づき、複数のクラスを実装する経験をした。
・他のクラスが未実装の場合、仮の値を設定しておくこともある。
・フィールドは、各クラスに適切な値のみ持つ。
・コンストラクターは、オブジェクト生成(インスタンス化)に必要な値を与える。
・メソッドは、各オブジェクトに必要な機能を実装する。
サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/** * Mainクラス * */ public class Main { public static void main(String...strings) { // 請求書オブジェクトを生成する。 Invoice invoice = new Invoice("Yamada Taro"); // 請求書オブジェクトに請求詳細のオブジェクトをいくつか追加する。 invoice.add(new InvoiceDetail("カレーライス", 800, 1)); invoice.add(new InvoiceDetail("お子様ランチ", 450, 2)); invoice.add(new InvoiceDetail("スパゲティ", 600, 1)); // 会計オブジェクトを生成する。 Account account = new Account(invoice); // 合計額を算出する。 System.out.println(invoice.billingName() + "様のお会計合計は、" + " " + account.totalInvoice() + "円です。"); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
/** * 会計クラス * */ public class Account { // フィールド private Invoice invoice; // コンストラクター Account(Invoice invoice){ this.invoice = invoice; } // メソッド public int tax() { double TAX_RATE = 0.1; return (int)(Math.ceil(invoice.totalAmount() * TAX_RATE)); } public int totalInvoice() { return invoice.totalAmount() + tax(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import java.util.ArrayList; import java.util.List; /** * 請求書クラス * */ public class Invoice { // フィールド private String billingName; private List<InvoiceDetail> invoiceDetailList; // コンストラクター Invoice(String billingName){ this.billingName = billingName; this.invoiceDetailList = new ArrayList<>(); } // メソッド public String billingName() { return billingName; } public void add(InvoiceDetail invoiceDetail) { invoiceDetailList.add(invoiceDetail); } public int totalAmount() { int total = 0; for(InvoiceDetail invoice: invoiceDetailList) { total += invoice.amount() * invoice.num(); } return total; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
/** * 請求明細クラス * */ public class InvoiceDetail { // フィールド private String name; private int amount; private int num; // コンストラクター InvoiceDetail(String name, int amount, int num){ this.name = name; this.amount = amount; this.num = num; } // メソッド public String name() { return name; } public int amount() { return amount; } public int num() { return num; } } |