ソフトウエア基礎

オブジェクト指向の復習(オブジェクトとクラス)

解説

提出課題

課題2-1

/* VideoExample.java - ビデオテープクラスの使用例
 */
class VideoTape {
    public int position=0;			// 現在の位置
    public void forward(int t) {		// tだけ先に早送りする
        position += t;
    }
    public void back(int t) {			// tだけ巻き戻す
        position -= t;
    }
}

public class VideoExample {
    public static void main(String[] args) {
        VideoTape vt = new VideoTape();
        System.out.println("最初の位置" + vt.position + "秒");
        vt.forward(600); // 600秒進める
        System.out.println("進めた後の位置" + vt.position + "秒");
        vt.back(150); // 150秒戻す
        System.out.println("巻き戻した後の位置" + vt.position + "秒");
   }
}

上記 VideoExample.java のVideoTapeクラスにあるbackメソッドの定義を以下に示すものに書きかえよ。 backメソッドで直接positionの値を変えるのではなく、 backメソッドからforwardメソッドを呼び出して動作するようにする。 すなわち、backメソッドは以下のようになる。

    public void back(int t) {			// tだけ巻き戻す
        ...
        forward( ... );
        ...
    }
}

ヒント: back(巻き戻し)はforward(早送り)の逆である。

課題2-2

課題2-1で利用した VideoExample.java のVideoTapeクラスは60分テープであるとする。 forwardメソッドで現在の位置が60分を超えないように、また、 backメソッドで0分を下回らないように、双方のメソッドを書きかえよ。
main()メソッドの中で、vt.forward(4000); と呼んだ場合、どうなるか?
main()メソッドの中で、vt.back(10); と呼んだ場合、どうなるか?

例えば、forward()とback()は以下のような形にすることができる。 (他にも方法はある)

    public void forward(int t) {		// tだけ先に早送りする
        if( ...) {  // 60分を超えるか確認
           ...      // 60分を超えないように調整する
        }
        position += t;
    }
    public void back(int t) {			// tだけ巻き戻す
        if( ...) {  // 0分を下回らないか確認
           ...      // 0分を下回らないように調整する
        }
        position -= t;
    }
}

ヒント: 現在の位置に早送りする量(または巻き戻す量)を加えた場合、テープの範囲に収まるか確認する必要がある

課題2-3

/* VideoExample2.java - ビデオテープクラスの使用例2
*/
class VideoTape {
    private int position=0;			// 現在の位置
    public int get_position() {			// 現在の位置を得る
        return position;
    }
    public void forward(int t) {		// tだけ先に早送りする
        position += t;
    }
    public void back(int t) {			// tだけ巻き戻す
        position -= t;
    }
}

public class VideoExample2 {
    public static void main(String[] args) {
        VideoTape vt = new VideoTape();
        System.out.println("最初の位置" + vt.get_position() + "秒");
        vt.forward(600); // 600秒進める
        System.out.println("進めた後の位置" + vt.get_position() + "秒");
        vt.back(150); // 150秒戻す
        System.out.println("巻き戻した後の位置" + vt.get_position() + "秒");
   }
}

上記 VideoExample2.java のmainメソッド中で、vt.get_position()の代わりに vt.position と書いた場合どうなるかを報告し、それがどういうことか説明せよ。
ヒント: VideoExample.java では、vt.position で問題なかった。 VideoExample.java と VideoExample2.java では何が違うのか? 特にアクセス制御に注目せよ。

課題2-4

課題2-2について、さらにテープの長さをオブジェクトが持つようにせよ。 つまり、VideoTapeクラスにlength というフィールドを追加し、 set_lengthというメソッドを定義せよ。 set_lengthはテープの長さ(秒)の引数を取る。 set_length を呼ぶとその VideoTape オブジェクトのテープの長さが設定される。 すなわち、set_length メソッドで length フィールドの値を設定する。
※ もちろん forward や back メソッドでテープの現在の位置がテープの長さを超えないようにする必要がある。

例えば、以下のような形になる。(他の方法もある)

/* VideoExample.java - ビデオテープクラスの使用例
 */
class VideoTape {
    public int position=0;			// 現在の位置

    ... int length;                             // テープの長さ(秒)

    public void set_length(...){                // テープの長さを設定する
       ...
    }

    public void forward(int t) {		// tだけ先に早送りする
        ...
    }
    public void back(int t) {			// tだけ巻き戻す
        ...
    }
}

public class VideoExample {
    public static void main(String[] args) {
        VideoTape vt = new VideoTape();
        vt.set_length( ... );
        ...
   }
}

課題2-5

従業員と管理者クラスを使うJavaプログラムを実行せよ。 このプログラムを以下のように修正せよ。Managerクラスに部下の一人当りの平均売上を 求める getAverageOfSales() メソッドを定義せよ。 また、describeDepartment()を呼び出した場合に、部下の一人当りの平均売上も 表示するようにせよ。
ヒント: to_String()メソッドを修正すればよい。

課題2-6

以下は平面上の点を表すオブジェクトのクラスである。

class Point {
    double x=0, y=0;
}

このPointクラスに、点の位置を移動するmoveメソッドを定義せよ。 移動量はmoveメソッドに与える引数で指定する。 例えば、以下の場合、p.move(20, -30)で、点pの位置をx方向に20、 y方向に-30移動させる。 つまり、moveを呼び出す前の表示が、x=100 y=50、呼び出した後の表示が、 x=120 y=30 となれば良い。

public class PointTest {
    public static void main(String[] args) {
        Point p = new Point();
        p.x = 100;
        p.y = 60;
        System.out.println("x=" + p.x + " y=" + p.y);
        p.move(20, -30);
        System.out.println("x=" + p.x + " y=" + p.y);
    }
}

課題2-7

課題2-6で、Pointオブジェクトのx座標の値とy座標の値を交換する swap_xyメソッドを定義せよ。 その動作が確認できるようなmainメソッドも記述すること。

課題2-8

課題2-6で、Pointクラスのxとyをprivateとし、点のx座標を得るメソッドgetxと、 y座標を得るメソッドgety、 点の位置をセットするメソッドset(xとyを引数に指定)を定義せよ。 それに伴い課題1のmainメソッドも書きかえよ。

課題2-9

線分を表すLineクラスを定義せよ。線分とは、2点間を結ぶ直線である。 課題2-6のPointクラスが参考になるだろう。 さらに、線分を移動するmoveメソッドも定義せよ。 それらの動作が確認できるようなmainメソッドも記述すること。
※ Lineクラスは、x1, y1, x2, y2 を持てばよい。

課題2-10

課題2-9と同様にLineクラスを定義せよ。ただし、x1, y2, x2, y2ではなく、 p1, p2 という2つのPointオブジェクトを持ち、その2点間を結ぶ直線とせよ。
※ Lineクラスの定義に以下のコンストラクタ(次回触れる)を書く必要がある。

class Line {
    〜〜〜
    Line() {
        p1 = new Point();
        p2 = new Point();
    }
    〜〜〜
}

課題2-11

オブジェクト指向によるモデリングの例として自動販売機が良く挙げられる。 以下に示す簡単な自動販売機に必要なデータ(フィールド)とメソッドを列挙せよ。 なおデータの型やメソッドの引数、戻り値などの詳細までは答える必要はない。 データやメソッドの名前とそれぞれの簡単な説明があれば良い。 (データの例:「コーラの在庫数」、メソッドの例:「コーラのボタンを押す」)

飲料の自動販売機を定義する。

課題2-12

課題2-11の自動販売機で、「コーラ」の購入ボタンを押した場合に、 コーラが出てくる条件を文章で記せ。


ソフトウエア基礎
このWebページは水谷正大、大見嘉弘、マッキンケネスジェームスが ソフトウェア入門・演習向けに作成したものを大見嘉弘が修正したものである。
mizutani@rsch.tuis.ac.jp ohmi@rsch.tuis.ac.jp mackin@rsch.tuis.ac.jp