Javaプログラミング基礎 演習問題

解答は

に提出しなさい。クラスファイル (〜.class) は提出しなくてよい。 提出には gFTP 等の ftp ソフトを用いること。

問題1 (Basic)

以下のやり方はプログラムの設計方法として正しいか否かを判断しなさい。 ○×で答え、その理由を述べること。 ファイル名は Q1.txt とする。

  1. 大学には必ず学部があるので、学部クラスを継承する形で大学クラスをつくった。
  2. 大学にも高校にも入試があり、出願手続きなどの手順は似通っている。そこで入試インタフェースを定義して、大学クラスと高校クラスの両方にそのインタフェースを実装した。
  3. HDD(ハードディスクドライブ)も光学ドライブもドライブという点では共通なので、まずドライブクラスをつくり、それをHDDクラスと光学ドライブクラスに継承させた。
  4. ビル建設も橋の建設も鉄骨が重要であることは共通なので、鉄骨クラスを継承し、ビルクラスと橋クラスをつくった。

問題2 (Basic)

今日の例題では2次元の図形としてのインタフェースを表す Shape を定義し、 円と矩形のクラスを定義した。

同様の考え方に基づき、3次元の図形としてのインタフェース ThreeDShapeを定義しなさい。3次元の図形には次のような機能があるとする。

ThreeDShape のインタフェースを実装し、 少なくとも 2 種類の立体図形を表すクラスを作成しなさい。 さらに、クラス SolidFigures に main メソッドを作成し、 表面積や体積を求める様子を書きなさい。 (ファイル名 SolidFigures.java)

問題3 (Standard)

前回の演習問題 で、3つのタイプの人を表わすクラスを作成した。 その際、人の共通の特徴を表すクラスとして基底クラス Person を定義し、 その Person クラスを継承させて、3つのタイプの人を表わすクラスを作成した。

ここでは別の考え方として、基底クラスを定義する代わりに、 「人」であることを表わすような共通のインタフェースを定義することを考える。 正直な年齢を答える人、10歳単位で四捨五入した年齢を答える人、 さばを読んだ年齢を答える人を表わすクラスを、 前述のインタフェースを実装する形で定義しなさい。

さばを読んだ年齢とは、年齢に応じてさばを読み度合を変化させるものとし、 20歳未満であれば実年齢、 20歳以上30歳未満であれば「実年齢-1」、 30歳以 上40歳未満であれば「実年齢-2」、 40歳以上50歳未満であれば「実年齢-3」、 50歳以上であれば「実年齢-4」を答えるものとする。

クラス InterfacedPeople に main メソッドと各自の自己紹介をする introduce メソッドを作成し、正直な人、いい加減な人、さばを読む人のそれぞれに自己 紹介をしてもらう。 (ファイル名 InterfacedPeople.java)

class InterfacedPeople {
    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();
    }
}

interface Person ....

class HonestPerson ....

class VaguePerson ....

class Liar ....

問題4 (Advanced)

あなたは、携帯音楽プレーヤにダウンロードした曲が増えすぎて、 どんな曲が入っているかもよくわからなくなってきたので、 曲の情報を Java のプログラムで管理することとした。 以下は、以前作成した Music クラスと、 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");

        for(int i = 0; i < song.length; i++) {
            System.out.println(i + ": " + song[i].getName() + " by " +
                               song[i].getArtist());
        }
    }
}

class Music {
    private String name;
    private String artist;
    public Music(String musicName, String artistName) {
        name = musicName;
        artist = artistName;
    }
    public String getName() {
        return name;
    }
    public String getArtist() {
        return artist;
    }
}

クラス 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 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].getArtist());
        }
    }
}

class Music ....

    // Comparable インタフェースを実装した Music クラスの内容を書く

}

なお、comapreTo メソッドは Object クラスの引数を受け取ることになるので、 引数の Object オブジェクトを Music オブジェクトとして使うためには以下のように キャストする必要がある。

public int compareTo(Object obj) {
    Music anotherSong = (Music)obj;
    ....
}