課題1901
架空の店「ほげマート」のレシートを表すクラス HogeMartReceipt をパッケージ j2.lesson06 に作成しなさい。
ほげマートのレシートの例を挙げる。
ほげマート 東京店 ============= 事務用品 5000円 筆記用具 120円 雑誌 220円 合計:5340円 ============= 加算ポイント:53 担当者: ふー
"=" で囲まれた部分の表示形式は、「ほげ書店」のレシートの "-" で囲まれた部分のそれと同様である。また、担当者はコンストラクタでその名前を指定し、加算ポイントは合計金額の1/100の小数点以下を切り捨てた値を表示する。
ほげ書店 TEL:03-xxxx-yyyy ---------------- (購入した商品) (購入した商品の価格)円 ... 合計: (価格の合計)円 ---------------- ありがとうございました。
このクラスは、演習で作成した AbstractReceipt クラスを継承して作成すること。どのメソッドをオーバーライドしてもかまわないが、このクラスを abstract として宣言しないこと。また、 AbstractReceipt, Receipt はそれぞれ変更しないこと。
HogeMartReceipt は次のようなpublicとして指定されたコンストラクタを用意すること。
- HogeMartReceipt(String clerk)
- 店員を指定してレシートのインスタンスを作成する。
- clerk - 店員の名前
- ここで指定した店員名が、レシートの「担当者:」の部分に出現する
クラスが完成したら、mainメソッドを用意してそこに簡単なプログラムを書いてみること。
手順
指定した箇所で必ずテストを行うこと。
- 各メソッドに対する詳細な擬似コードを作成する
- パッケージ j2.lesson06 にクラス HogeMartReceipt を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- テスト項目「HogeMartReceiptに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「HogeMartReceiptに対する単体テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(クラス名), not abstract | クラスを作る際に abstract を指定してしまっている |
(クラス名), extends <C> | クラスを作る際に継承するクラスが間違っている。正しくは <C> |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), protected | メンバを作る際に protected の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。テスト項目を参照 |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
show_void | new HogeMartReceipt("a").show() |
show_99 | new HogeMartReceipt("b"), addItem("c", 99), show() |
show_100 | new HogeMartReceipt("b"), addItem("c", 100), show() |
show_sample | new HogeMartReceipt("b"), addItem("p1", 198), addItem("p2", 198), addItem("p3", 198), show() |
課題1902
「ほげ書店」の正式な領収書を表すクラス HogeBooksAcquittance をパッケージ j2.lesson06 に作成しなさい。
このクラスは、次のインターフェース Acquittanceを実装すること。
package j2.lesson06; public interface Acquittance { // 支払人の名前を取得する String getPayerName(); // 発行者の名前を取得する String getIssuerName(); // 合計金額を取得する int getTotalAmount(); // 但し書きを取得する String getFinePrint(); // 領収書全体を表示する void show(); }
「ほげ書店」の正式な領収書は、次のような形式である。
領収書 (支払人)様 ¥(合計金額).- (但し、(但し書き)として) 確かに領収いたしました。 (発行者)
「支払人」「合計金額」「但し書き」「発行者」はそれぞれ getPayerName(), getTotalAmount(), getFinePrint(), getIssuerName() を呼び出した結果と同じである。
このクラスには、次のような public で宣言されたコンストラクタ、およびインスタンスメソッドを用意すること。
- public HogeBooksAcquittance()
- 正式な領収書のインスタンスを生成する。
- 支払人、合計金額、但し書きの初期値は次のようになっている。
- 支払人 - "上"
- 合計金額 - 0
- 但し書き - "お品代"
(最近は上様宛ての領収書は発行してくれないので、現実で試さないように。)
- public String getPayerName()
- 支払人の名前を取得する。
- 定義: インタフェース Acquittance 内の getPayerName
- 戻り値: 支払人の名前
- public void setPayerName(String payer)
- 支払人の名前を設定する。設定した値は getPayerName() で取得できる。
- payer - 支払人の名前
- public String getIssuerName()
- 発行者の名前を取得する。このクラスでは常に "ほげ書店"。
- 定義: インタフェース Acquittance 内の getIssuerName
- 戻り値: 発行者の名前
- public int getTotalAmount()
- 合計金額を取得する。
- 定義: インタフェース Acquittance 内の getTotalAmount
- 戻り値: 合計金額
- public void setTotalAmount(int totalAmount)
- 合計金額を設定する。設定した値は getTotalAmount() で取得できる。
- totalAmount - 合計金額
- public String getFinePrint()
- 但し書きを取得する。
- 定義: インタフェース Acquittance 内の getFinePrint
- 戻り値: 但し書き
- public void setFinePrint(String finePrint)
- 但し書きを設定する。設定した値は getFinePrint() で取得できる。
- finePrint - 但し書き
- public void show()
- この領収書全体を表示する。
- インタフェース Acquittance 内の show
show() メソッドは以下のものを使ってよい。別の書き方をしてもかまわないが、出力は下記のものと揃えること。
// この領収書全体を表示する public void show() { // print "領収書", 改行 System.out.println("領収書"); // print (支払人) + "様", 改行 System.out.println(getPayerName() + "様"); // print "¥" + (合計金額) + ".-", 改行 System.out.println("¥" + getTotalAmount() + ".-"); // print "(但し、" + (但し書き) + "として)", 改行 System.out.println("(但し、" + getFinePrint() + "として)"); // print "確かに領収いたしました。", 改行 System.out.println("確かに領収いたしました。"); // print " " + (発行者), 改行 System.out.println(" " + getIssuerName()); }
また、これを動かす簡単な main メソッドを用意して実行してみること。
手順
指定した箇所で必ずテストを行うこと。
- 各メソッドに対する詳細な擬似コードを作成する
- パッケージ j2.lesson06 にクラス HogeBooksAcquittance を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- テスト項目「HogeBooksAcquittanceに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「HogeBooksAcquittanceに対する単体テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(クラス名), not abstract | クラスを作る際に abstract を指定してしまっている |
(クラス名), extends <C> | クラスを作る際に継承するクラスが間違っている。正しくは <C> |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), protected | メンバを作る際に protected の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。テスト項目を参照 |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
show_void | new HogeBooksAcquittance().show() |
show_fully | new HogeBooksAcquittance(), setPayerName("a"), setTotalAmount(5000), setFinePrint("b"), show() |
課題1903 (optional)
ほげ書店のレシート兼領収書を表すクラス HogeBooksHybridReceipt をパッケージ j2.lesson06 に作成しなさい。
最近のレシートは、正式な領収書として使えるものがある。これは、レシート上部が正式な領収書の形式をとっていて、下部に通常のレシートが印刷されているものである。
架空の店舗「ほげ書店」では、次のようなレシート兼領収書を発行することになった。
領収書 ふー様 ¥780.- (但し、書籍代として) 確かに領収いたしました。 ほげ書店 ================ ほげ書店 TEL:03-xxxx-yyyy ---------------- 雑誌 250円 文庫 530円 合計:780円 ---------------- ありがとうございました。
これは、全体を "="の繰り返し で区切って、上部に HogeBooksAcquittance の show() メソッドを呼び出した結果を、下部に HogeBooksReceipt の show() メソッドを呼び出した結果を表示している。
HogeBooksHybridReceipt は、インターフェース Receipt と Acquittance をそれぞれ実装し、次のようなpublicとして指定されたコンストラクタ、インスタンスメソッドを用意すること。
ただし、2つのインターフェースは直接実装しなくても (親の誰かが実装しているだけでも) よい。そのため、下記の全てのメソッドを HogeBooksHybridReceipt 内で実装しなくても、親の誰かが実装していればよい。
- public HogeBooksHybridReceipt()
- レシート兼領収書のインスタンスを作成する。
- public void show()
- この領収書兼レシートを表示する。
- public void addItem(String name, int cost)
- 購入した商品を追加する。
- name - 商品の名前
- cost - 商品の単価
- public int getTotalAmount()
- 合計金額を取得する。
- 定義: インタフェース Receipt 内の getTotalAmount
- 戻り値: 合計金額
- public String getPayerName()
- 支払人の名前を取得する。
- 定義: インタフェース Acquittance 内の getPayerName
- 戻り値: 支払人の名前
- public void setPayerName(String payer)
- 支払人の名前を設定する。
- payer - 支払人の名前
- public String getIssuerName()
- 発行者の名前を取得する。
- 定義: インタフェース Acquittance 内の getIssuerName
- 戻り値: 発行者の名前
- public String getFinePrint()
- 但し書きを取得する。
- 定義: インタフェース Acquittance 内の getFinePrint
- 戻り値: 但し書き
- public void setFinePrint(String finePrint)
- 但し書きを設定する。
- finePrint - 但し書き
setPayerName, setFinePrint メソッドが一度も呼び出されていない場合の表示は、HogeBooksAcquittance クラスを扱った際に同名のメソッドが一度も呼び出されていない場合と同じものを領収書部分に表示すること。
この課題で注意すべき点として、上記の仕様の中に setTotalAmount() メソッドが存在しないという点である。領収書部分を表示する際には注意すること。
手順
指定した箇所で必ずテストを行うこと。
- 各メソッドに対する詳細な擬似コードを作成する
- パッケージ j2.lesson06 にクラス HogeBooksHybridReceipt を作成
- クラス内に必要なコンストラクタ、メソッドの骨格を作成
- テスト項目「HogeBooksHybridReceiptに対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く (main メソッド以外)
- 各メソッドをテストする (JUnitを用いてもよい)
- 単体テスト 「HogeBooksHybridReceiptに対する単体テスト」 をパス
- mainメソッドを実装する
- 実際に実行して動作を確認する
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(クラス名), extends <C> | クラスを作る際に継承するクラスが間違っている。正しくは <C> |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), private | メンバを作る際に private の指定がない |
(メンバ名), final | メンバを作る際に final の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。テスト項目を参照 |
未初期化フィールド | インスタンスを代入すべきフィールドにインスタンスを代入していない可能性がある |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
show_void | new HogeBooksHybridReceipt().show() |
show_sample | new HogeBooksHybridReceipt(), addItem("a", 5000), setPayerName("b"), setFinePrint("c"), show() |
課題1904 (optional)
既約分数を表すクラス Rational をパッケージ j2.lesson06 に作成しなさい。
既約分数とはそれ以上約分することのできない分数のことである。通常の分数を既約分数に変換するには、分子と分母をそれらの最大公約数で割ってやればよい。ただし、このクラスが表す既約分数には、次のようなルールを与える。
- このインスタンスが持つ分子、分母からなる分数は既約分数である
- 分子が0の場合は分母は必ず1とする
- 分母が0の場合については考慮しなくてもよい
- 分母は必ず正の値である (2/-3 -> -2/3)
Java には数値全般を表すクラスとして、java.lang.Number というクラスが存在する。既約分数 is-a Number であるので、このクラスを Rational が継承すること。
次のようなpublicとして指定されたコンストラクタ、インスタンスメソッドを用意すること。これ以外のメンバを用意してもよいが、その際は private で宣言すること。
- public Rational(int numerator, int denominator)
- 既約分数インスタンスを生成する。
- numerator - 分子
- denominator - 分母
- この分数は既約分数であるが、コンストラクタに与えられる2つの引数が既約分数の形をしているとは限らない。そのため、コンストラクタ内で numerator と denominator を既約分数の形にしてやるとよい。
- public Rational add(Rational r)
- この分数と他の分数を加算した結果を表す、新しい分数を返す。
- この操作によってもとの分数が変更されることはない。
- r - 加算する値
- 戻り値: 2つの分数を加算した結果の新しい分数
- public Rational sub(Rational r)
- この分数から他の分数を減算した結果を表す、新しい分数を返す。
- この操作によってもとの分数が変更されることはない。
- r - 減算する値
- 戻り値: 2つの分数を減算した結果の新しい分数
- public Rational multiply(Rational r)
- この分数と他の分数を乗算した結果を表す、新しい分数を返す。
- この操作によってもとの分数が変更されることはない。
- r - 乗算する値
- 戻り値: 2つの分数の積
- public Rational divide(Rational r)
- この分数から他の分数を割った商を表す、新しい分数を返す。
- この操作によってもとの分数が変更されることはない。
- r - 割る値
- 戻り値: 2つの分数の商
- public String toString()
- この分数を既約分数として文字列に変換する。
- 表示形式は (分子) + "/" + (分母)。 既約分数であるので、new Rational(3, 6).toString() は"1/2"を返す必要がある。
- 分子が0の場合は必ず"0/1"を返す。
- 約分によって分母が1になった場合も、分母は表示する ("n/1")。
- 分母の値は必ず正の値である必要がある。
- 戻り値: この分数の文字列表現
また、Number クラスにはいくつかの abstract メソッドが存在する。このクラスを継承しているので、次のメソッドをオーバーライドすること。
- public int intValue()
- この分数を int 型で表した値を返す。
- int 型で表せない範囲は切り捨てられる。
- 戻り値: この分数を int 型で表した値
- public long longValue()
- この分数を long 型(*1) で表した値を返す。
- intValue() と同じ値を返す。
- 戻り値: return intValue()
- 関連項目: intValue()
- public float floatValue()
- この分数を float 型(*1) で表した値を返す。
- 戻り値: return (float) doubleValue()
- 関連項目: doubleValue()
- public double doubleValue()
- この分数を double 型で表した値を返す。
- double型で表せない範囲は切り捨てられる。
- int 型の値を double 型に変更するには、「(double) int型の値」とすればよい(*2)
- 戻り値: この分数を double 型で表した値
- (*1) long, float は授業内で紹介していないので、これらのメソッドは解答例を示す。
public long longValue() { return this.intValue(); }
public float floatValue() { return (float) this.doubleValue(); }
- (*2) 次回の授業で紹介する予定だが、数値を別の型に変換する場合には「(変換先の型) 変換する値」とする。
int a = 10; int b = 3; double c = (double) a / (double) b;
上記のように書くことによって、c には 3 ではなく 3.33333... が代入される。
また、Rational クラス内に簡単な main メソッドを用意し、動作を確認すること。
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j2.lesson06 にクラス Rational を作成
- 指定したインスタンスメソッドやコンストラクタを作成する
- main メソッドを作成する (この時点では空でもよい)
- テスト項目「Rationalに対する骨格テスト」をパス
- インスタンスメソッドやコンストラクタの中身を書く (演習と同様)
- main メソッドを書いて簡単なテストを行う
- JUnit を用いてもよい
- テスト項目「Rationalに対する単体テスト」をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(クラス名), extends <C> | クラスを作る際に継承するクラスが間違っている。正しくは <C> |
(メンバ名), existence | 指定されたメンバが存在しない |
(メンバ名), public | メンバを作る際に public の指定がない |
(メンバ名), private | メンバを作る際に private の指定がない |
(メンバ名), final | メンバを作る際に final の指定がない |
(メンバ名), not static | メンバを作る際に static が余計についている |
(メンバ名), type <T> | メンバを作る際に型の指定を間違っている。正しくは <T> |
単体テスト
メッセージ | 詳細 |
---|---|
期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。テスト項目を参照 |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
toString_0 | new Rational(0, 100).toString() |
toString_M1a | new Rational(-1, 1).toString() |
toString_M1b | new Rational(1, -1).toString() |
toString_1a | new Rational(1, 1).toString() |
toString_1b | new Rational(100, 100).toString() |
add | new Rational(3, 5).add(new Rational(2, 5)).toString() |
sub | new Rational(3, 5).add(new Rational(1, 10)).toString() |
multiply | new Rational(3, 4).multiply(new Rational(4, 3)).toString() |
divide | new Rational(10, 1).divide(new Rational(1, 10)).toString() |
intValue | new Rational(12, 5).intValue() |
doubleValue | new Rational(12, 5).doubleValue() |