キャッシュレジスターをプログラムする。
レジで会計する(税込の合計金額を計算してレシートを印刷する)ときに必要なのは、商品の値段と商品名だ。だから、Bookクラスに「値段を取得するメソッド」と「商品名を取得するメソッド」があればOK。
では、Bookで表現できないものをレジで会計するには、どのようにすればいいのか?
- Book以外も受け付けるようにレジを改良する(クラスごとに保存、計算するプログラムが必要になる)。
- Bookより上位のクラス(例えば商品クラス)を定義し、それを継承するように書き直す(Java言語は単一継承のためうまく実現できない場合も)。
- getPriceメソッドをなんとかして呼ぶ(リフレクションを使う)。ちなみに、ダック・タイピングをサポートする言語ならば簡単だが、Java言語はそうでは無い。
- 商品を表すインターフェースを定義し、レジで扱いたいクラスはそれを実装(implements)する。
- etc…
インターフェースとは
クラスに特定のメンバー(メソッドとフィールド、主にメソッド)が存在することを保証する仕組み。クラスと同様に型として扱うことができる。
- インターフェースには「クラスが持っていてほしいメンバー」を定義する。ただしメソッドの本体(実際に実行される部分)は無い(抽象メソッドという)。
- インターフェースをimplementsしたクラスは、そのインターフェースに定義されているメンバー全体を実装する(メソッドの本体も書く)。
まずはBookだけを計算できるレジ
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 |
package lesson12.d00000; import lesson11.d00000.Book; import java.util.ArrayList; public class CashRegister { private ArrayList<Book> bookArrayList; public CashRegister() { this.bookArrayList = new ArrayList<Book>(); } public void addBook(Book p) { bookArrayList.add(p); } public void clear() { this.bookArrayList.clear(); } public void printReceipt() { int total = 0; for (Book p : bookArrayList) { System.out.println(p.title + "\t" + p.getPrice() + "円"); total += p.getPrice(); } int tax = (int)(0.08 * total); System.out.println("------------------------"); System.out.println("小計" + "\t" + total + "円"); System.out.println("税" + "\t" + tax + "円"); System.out.println("合計" + "\t" + (total + tax) + "円"); } } |
1 2 3 4 5 |
CashRegister cashRegister = new CashRegister(); cashRegister.addBook(new Book("Java逆引きレシピ", "竹添他", 2800)); cashRegister.addBook(new Comic("ドラゴンボール", "鳥山", 500, 1)); cashRegister.printReceipt(); cashRegister.clear(); |
商品を表すProduct
- クラスと同様にメンバー(フィールド、メソッド)を持つ。
- ただし、メソッドは本体がない(抽象メソッド)。
1 2 3 4 5 6 |
package lesson12.d00000; public interface Product { int getPrice(); // 価格を取得するメソッド String getName(); // 商品名を取得するメソッド } |
Productを実装(implements)
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 |
package lesson11.d00000; import lesson12.d00000.Product; public class Book implements Product { public String title; public String author; private int price; public Book(String title, String author, int price) { this.title = title; this.author = author; this.price = price; } public String getInfo() { String info = title + ", " + author +", " + price + "円"; return info; } @Override public String toString() { return getInfo(); } @Override public int getPrice() { return price; } @Override public String getName() { return title + "(" + author + ")"; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package lesson12.d00000; public class BoxedLunch implements Product { private String name; // 商品名 private int unitPrice; // 100グラムあたりの値段 private int amount; // 購入する量(グラム) public BoxedLunch(String name, int unitPrice, int amount) { this.name = name; this.unitPrice = unitPrice; this.amount = amount; } @Override public int getPrice() { return (int)(unitPrice/100.0 * amount); } @Override public String getName() { return name + "(" + amount + "グラム)"; } } |
Product対応レジ
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 |
package lesson12.d00000; import java.util.ArrayList; public class CashRegister { private ArrayList<Product> productList; public CashRegister() { this.productList = new ArrayList<Product>(); } public void addProduct(Product p) { productList.add(p); } public void clear() { this.productList.clear(); } public void printReceipt() { int total = 0; for (Product p : productList) { System.out.println(p.getName() + "\t" + p.getPrice() + "円"); total += p.getPrice(); } int tax = (int)(0.08 * total); System.out.println("------------------------"); System.out.println("小計" + "\t" + total + "円"); System.out.println("税" + "\t" + tax + "円"); System.out.println("合計" + "\t" + (total + tax) + "円"); } } |
1 2 3 4 5 6 |
CashRegister cashRegister = new CashRegister(); cashRegister.addProduct(new Book("Java逆引きレシピ", "竹添他", 2800)); cashRegister.addProduct(new Comic("ドラゴンボール", "鳥山", 500, 1)); cashRegister.addProduct(new BoxedLunch("鶏肉と里芋の煮物", 178, 200)); cashRegister.printReceipt(); cashRegister.clear(); |