Javaプログラミング基礎

演習問題

解答は

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

問題1 (Basic)

前々回の例題で 「クラスを用いた電卓のプログラム」を示した。 このプログラムは整数 (int型) 同士の四則演算を行うものであった。 このプログラムを元に、 整数 (int型)、実数 (double型) 両方に対応した電卓プログラムに改良しなさい。

具体的には、add, sub, multi, divide の各メソッドをオーバロードする形で、 実数 (double型) 同士の四則演算を行うメソッドを追加しなさい。 また、メモリ機能は double 型のみに対応するように変更しなさい。

電卓のクラス名は Calculator 、 メソッド main を置くクラス名は OverloadedCalculation とする。 (ファイル名は OverloadedCalculation.java)

class OverloadedCalculation {
    public static void main(String[] args) {
        Calculator calc = new Calculator();

        // int型同士の計算を行う
        System.out.println("1 + 2 = " +  calc.add(1, 2) );

        // double型同士の計算を行う
        System.out.println("3.3 - 2.5 = " +  calc.sub(3.3, 2.5) );

        // 6.5 * (2.2 - 1.8) を計算
        // まず 2.2 - 1.8 を計算しメモリに記憶
	calc.setMemory(calc.sub(2.2, 1.8));
        // メモリから値を取り出し 6.5 と掛け算
	double ans = calc.multi(6.5, calc.getMemory());

        System.out.println("6.5 * (2.2 - 1.8) = " + ans);
    }
}

class Calculator {

     int型の値同士の四則演算と、
     double型の値同士の四則演算を行うメソッドを書く

     メモリ機能を double 型の値のみを扱うように変更する

}

問題2 (Basic)

前々回の例題 「例題: 成長するサボテン」では、 1年に一定の長さで成長するサボテンの高さを計算するプログラムを示した。

サボテンの最初の高さと成長率は1つのサボテンを表わすためには必須の情報なので、 オブジェクトを作成する際に初期化することにする。 クラス Cactus を改良し、 コンストラクタを用いて最初の高さと成長率を初期化できるようにしなさい。

プログラムの枠組みは以下のとおり。 メソッド main のあるクラス名は InitializedCactusObservation1 とし、 ファイル名は InitializedCactusObservation1.java とする。

class InitializedCactusObservation1 {
    public static void main(String[] args) {
        // 高さ 100mm = 10cm 、成長率年間 5mm としたサボテンを生成
        Cactus myCactus = new Cactus(100, 5);

	System.out.println("現在のサボテンの背丈は " + myCactus.getHeight());

        // 1年後の経過をみる
        myCactus.grown(1);
	System.out.println("現在のサボテンの背丈は " + myCactus.getHeight());

        // さらにそれから2年後の経過をみる
        myCactus.grown(2);
	System.out.println("現在のサボテンの背丈は " + myCactus.getHeight());
    }
}

class Cactus {
    int height;
    int growth;

    // ここに適切なコンストラクタを書く

    void setHeightAndGrowth(int x, int y) {
        height = x;
        growth = y;
    }

    void grown(int years) {
        height = height + growth * years;
    }

    int getHeight() {
        return height;
    }
}

問題3 (Standard)

上の Cactus クラスをさらに改良し、

Cactus myCactus1 = new Cactus(100, 5);

のようにオブジェクトを作成した際は、高さと成長率がそれぞれ 100mm と 5mm に初期化され、

Cactus myCactus2 = new Cactus(100);

のように成長率を省略してオブジェクトを作成した際は、 高さは 100mm 、成長率は自動的に 1mm に初期化され、さらに、

Cactus myCactus3 = new Cactus();

のようにすべてのパラメータを省略した場合、 高さと成長率は自動的にそれぞれ 10mm と 1mm に初期化されるようにしなさい。

また、 main メソッドを変更し上のように異なった3つの方法で初期化した サボテンが成長する様子を表示するようにしなさい。

プログラムの枠組みは以下のとおり。 メソッド main のあるクラス名は InitializedCactusObservation2 とし、 ファイル名は InitializedCactusObservation2.java とする。

class InitializedCactusObservation2 {
    public static void main(String[] args) {
        // 高さ 100mm = 10cm 、成長率 5mm としたサボテン myCactus1 を生成
        Cactus myCactus1 = new Cactus(100, 5);

        // 高さ 100mm = 10cm 、成長率を省略したサボテン myCactus2 を生成
        Cactus myCactus2 = new Cactus(100);

        // すべてのパラメータを省略したサボテン myCactus3 を生成
        Cactus myCactus3 = new Cactus();

       
        // 3つのサボテンについて1年後の経過をみる
        // さらにそれから2年後の経過をみる

    }
}

class Cactus {
    int height;
    int growth;

    // ここに複数のコンストラクタを書く:
    // ・長さと成長率が指定されていた場合、指定された長さと成長率に初期化する。
    // ・長さのみが指定されていた場合、指定された長さと成長率 1mm に初期化する。
    // ・すべて省略されていた場合、長さを 10mm 、成長率を 1mm に初期化する。

    void setHeightAndGrowth(int x, int y) {
        height = x;
        growth = y;
    }

    void grown(int years) {
        height = height + growth * years;
    }

    int getHeight() {
        return height;
    }
}

問題4 (Standard)

前回の演習問題 で、オブジェクト指向の考え方を用いたボールのアニメーションを行う プログラムを作成した。

このプログラムを改造し、 3つのボールが移動するようにし、 ボール同士がぶつかった際に方向に応じて跳ね返ることを考えなさい。 ボール同士がぶつかったかどうかの判定は、 2つのボールの座標が一致したときにぶつかったと判定すれば良いこととする。

メソッド main のあるクラス名は ThreeBallsSimulation とし、 ファイル名は ThreeBallsSimulation.java とする。

このプログラムの大枠は次のようになる。 適切なコンストラクタについても考えること。

class ThreeBallsSimulation {
    public static void main(String[] args) {

        Ball ball1 = new Ball( ...... );
        Ball ball2 = new Ball( ...... );
        Ball ball3 = new Ball( ...... );

        while(true) {

            // ball1, ball2, ball3 が移動するようなプログラムを書く

        }
    }
}

class Ball {
    // クラス Ball の内容をここに書く

    // 適切なコンストラクタを書くこと
    // さらにメソッドを追加する必要があるはず

}

問題5 (Advanced)

さらに、10個や100個のボールが相互作用するように拡張することを考える。 上の問題のプログラムを元に、 数多くのボールを扱えるように改良しなさい。 メソッド main のあるクラス名は ManyBallsSimulation とし、 ファイル名は ManyBallsSimulation.java とする。

これを実現するには、 クラス Ball のオブジェクトを配列にする方法が考えられる。

class ManyBallsSimulation {
    public static void main(String[] args) {
        // 4つのボールの例
	Ball[] balls = new Ball[4];

        balls[0] = new Ball(....);
        balls[1] = new Ball(....);
        balls[2] = new Ball(....);
        balls[3] = new Ball(....);

        while(true) {

            // balls[0], balls[1], ..., balls[n] が移動するようなプログラムを書く

        }
    }
}

class Ball {
    // クラス Ball の内容をここに書く
    // 設計によってはメソッドを追加する必要があるかも知れない
}

(class ....  // 設計によってはクラスを追加する必要があるかも知れない )