解答は
- ホスト名: earth.mlab.im.dendai.ac.jp
- ディレクトリ: /home/submit/1I-Computer2/[出題日]/[学籍番号]
に提出しなさい。ソースファイル (〜.java) のみを提出。 提出は gFTP 等の ftp ソフトを用いて行う。
前回の演習問題 で、3つのタイプの人を表わすクラスを作成した。 その際、人の共通の特徴を表すクラスとして基底クラス Person を定義し、 その Person クラスを継承させて、3つのタイプの人を表わすクラスを作成した。
ここでは別の考え方として、基底クラスを定義する代わりに、 「人」であることを表わすような共通のインタフェースを定義することを考える。 正直な年齢を答える人、10歳単位で四捨五入した年齢を答える人、 さばを読んだ年齢を答える人を表わすクラスを、 前述のインタフェースを実装する形で定義しなさい。
さばを読んだ年齢とは、年齢に応じてさばを読み度合を変化させるものとし、 20歳未満であれば実年齢、 20歳以上30歳未満であれば「実年齢-1」、 30歳以 上40歳未満であれば「実年齢-2」、 40歳以上50歳未満であれば「実年齢-3」、 50歳以上であれば「実年齢-4」を答えるものとする。
クラス InterfacedPeople に main メソッドと各自の自己紹介をする introduce メソッドを作成し、正直な人、いい加減な人、さばを読む人のそれぞれに自己 紹介をしてもらう。 (ファイル名 InterfacedPeople.java)
class VariousPeople { public static void main(String[] args) { HonestPerson maurice = new HonestPerson("Maurice White", 24); VaguePerson philip = new VaguePerson("Philip Bailey", 32); Liar jonny = new Liar("Jonny Graham", 45); introduce(maurice); introduce(philip); introduce(jonny); } private static void introduce(Person p) { System.out.println("Hello, my name is " + p.getName()); System.out.println("I'm " + p.getAge() + " years old."); System.out.println(); } } ......
あなたはスーパの経営者となり、 スーパの業務をコンピュータ化したいと思っているとする。 そこで、商品と、商品の清算をするレジについて考えてみよう。
商品には、肉や魚、果物などがある。 これらの商品には「値段を求めることができる」 という意味では共通のインタフェースを持つことが考えられる。 また、レジでは「値段を求めることができる」商品の金額を計算し、 合計やお釣りの計算ができると考えられる。
スーパの商品に共通する「値段を求めることができる」 ということを Java のインタフェースで定義しなさい。 以下のように、インタフェース名は Merchandise とする。
interface Merchandise { ...... 値段を計算するためのメソッドの宣言をここに書く }
次に、肉、魚、果物の3つの商品をクラスとして表わすことを考えよう。 肉、魚、果物、いずれも商品であることは共通であることから、 各商品を、 上で定義したインタフェース Merchandise を実装するクラスとして定義しなさい。 なお、各商品の値段は以下のように計算されるものとする。
以下のように、肉、魚、果物、それぞれを表わすクラスを、 Meat, Fish, Fruit という名前で定義しなさい。
class Meat ............... { 属性 値段を計算するメソッド } class Fish ............... { 属性 値段を計算するメソッド } class Fruit ............... { 属性 値段を計算するメソッド }
なお、文字列同士が等しいかの比較をするには、メソッド equals を使うこと。
例: if (sweetness.equals("甘い")) { 変数 sweetness の内容が「甘い」と等しいときの処理をここに書く }
さらに、商品の清算を行うレジをクラスとして表わすことを考えよう。 レジでは、各商品の金額を計算し、 払った金額に対してお釣りを計算することができることとする。 以下を参考にし、このようなレジを表わすクラス Register を定義しなさい。
class Register { 属性 商品 メソッド 清算する商品を登録するメソッド (setMerchandise) 支払った金額から商品の値段を引いたお釣りを計算するメソッド (check) }
というわけで、これら考え方に基づき、 商品を清算する様子は以下のメソッド main で 表わすことができる。
class Consumer { public static void main(String[] args) { Register register = new Register(); // 300g の肉を買うために 2000 円払う System.out.println("300gの肉を買うために2000円払います。"); Meat steak = new Meat(300); register.setMerchandise(steak); System.out.println("お釣りは" + register.check(2000) + "円です。"); System.out.println(); // 2 切れの魚を買うために 1000 円払う System.out.println("2切れの魚を買うために1000円払います。"); Fish sashimi = new Fish(2); register.setMerchandise(sashimi); System.out.println("お釣りは" + register.check(1000) + "円です。"); System.out.println(); // 甘い果物を買うために 1000 円払う System.out.println("甘い果物を買うために1000円払います。"); Fruit apple = new Fruit("甘い"); register.setMerchandise(apple); System.out.println("お釣りは" + register.check(1000) + "円です。"); } }
ここまで説明した考え方により各インタフェース、クラスを定義し プログラムを完成させなさい。 (ファイル名 Consumer.java)
あなたは、携帯音楽プレーヤにダウンロードした曲が増えすぎて、 どんな曲が入っているかもよくわからなくなってきたので、 曲の情報を Java のプログラムで管理することとした。 以下は、以前作成した Music クラスと、 Music クラスのオブジェクトを配列として扱うプログラムである。
class Music { private String name; private String musician; public Music(String musicName, String musicianName) { name = musicName; musician = musicianName; } public String getName() { return name; } public String getMusician() { return musician; } } class MusicCollector { public static void main(String[] args) { Music[] song = new Music[4]; song[0] = new Music("Speak Like A Child", "Herbie Hancock"); song[1] = new Music("Kung-Fu World Champion", "Hiromi Uehara"); song[2] = new Music("We're All Alone", "Boz Scaggs"); song[3] = new Music("Moments Notice", "John Coltrane"); for(int i = 0; i < song.length; i++) { System.out.println(i + ": " + song[i].getName() + " by " + song[i].getMusician()); } } }
クラス MusicCollector では Music オブジェクトの配列を扱っているが、 この配列を曲名のアルファベット順 (辞書順) に並び替えることを考えよう。 Java のクラスライブラリには、配列の探索 (サーチ) や整列 (ソート) を行うための クラス Arrays がある ( Java の API の Arrays クラスの説明 参照)。 Arrays クラスの sort メソッドを利用すれば曲名順に並び替えることができる。
sort メソッドによって曲名順に並べ替えを行なうには、 Music クラスが Comparable インタフェースを実装している必要がある。 (Comparable インタフェースも Java のクラスライブラリに用意されている。) ( Java の API の Comparable インタフェースの説明 参照)。
Music クラスに Comparable インタフェースを実装するためには、 2 つの Music オブジェクトの間で大小関係が言えるように、 Music クラスに他の Music オブジェクトとの大小を返すメソッド compareTo(Object obj) を作成する必要がある。
compareTo メソッドは、 引数が任意のインスタンスを意味する Object クラスのオブジェクト、 戻り値が int 型とし、 このオブジェクトが比較対象のオブジェクトよりも 辞書順で前に並べるべきであれば -1、等しければ 0、 辞書順で後ろに並ぶべきならば 1 を返すこととする。 (Object クラスは、特に継承関係を明示しなくても全てのクラスのスーパクラスとなるような、 Java にあらかじめ 用意された特別なクラスである。したがって Music クラスも Object クラスの サブクラス (継承関係にある) である。)
ヒント: String クラスの辞書順比較をするメソッドを使うと良い。
以上のことを行い、Comparable インタフェースを実装した Music クラスを作成しなさい。
Comparable インタフェースを実装した Music オブジェクトの配列は、 Arrays.sort(song) として並び替えを行うことができる。 プログラムの例は次のようになる (ファイル名 MusicCollector.java)。
import java.util.Arrays; // Arrays クラスを使うためのおまじない class Music .... // Comparable インタフェースを実装した Music クラスの内容を書く } class MusicCollector { public static void main(String[] args) { Music[] song = new Music[4]; song[0] = new Music("Speak Like A Child", "Herbie Hancock"); song[1] = new Music("Kung-Fu World Champion", "Hiromi Uehara"); song[2] = new Music("We're All Alone", "Boz Scaggs"); song[3] = new Music("Moments Notice", "John Coltrane"); // song の内容を曲名のアルファベット順に並び替え Arrays.sort(song); for(int i = 0; i < song.length; i++) { System.out.println(i + ": " + song[i].getName() + " by " + song[i].getMusician()); } } }
なお、comapreTo メソッドは Object クラスの引数を受け取ることになるので、 引数の Object オブジェクトを Music オブジェクトとして使うためには以下のように キャストする必要がある。
public int compareTo(Object obj) { Music anotherSong = (Music)obj; .... }