トップ 差分 一覧 Farm ソース 検索 ヘルプ PDF RSS ログイン

演習4【自動車】

オブジェクト指向プログラミング

自動車とその所有者のクラス定義

所有者が自動車を運転することをプログラム化する。

 自動車クラスCarの定義

このクラスでは次の表のフィールドとメソッドを持つものとする。
項目 名前 内容など
フィールド speed int型 速度 初期値は0
メソッド accelerate() 戻り値なし 加速!br加速すると速度が10km/h増加し、現在の速度を表示する。
brake() 戻り値なし 停止!br減速すると速度は0km/hになり、停止したことを表示する

// 自動車クラス
class [1] {
  // フィールド
  int speed;
  // コンストラクタ
  [2] {
    speed = [3];
  }
  // 加速メソッド
  void [4] {
    speed += [5];
    System.out.println("Speed = " + speed + "km/h");
  }
  // 減速メソッド
  void [6] {
    speed = [7];
    System.out.println("停止しました.");
  }
}

 所有者のクラスOwnerの定義

自動車を所有し、それを運転する人を定義したクラス。次の表に示すフィールドとメソッドを持つ。

項目 名前 内容
フィールド myCar Car Carクラスオブジェクト
コンストラクタ Owner 自動車オブジェクトmyCarを作る(車を所有する)
メソッド drive() void 自動車myCarを運転する!br適当に加速、停止の動作をする
mainメソッド void 所有者のオブジェクトdriverを作る!br所有者driverが車を運転する

// Ownerクラス
class [1] {
  // フィールド
  Car [2];
  // コンストラクタ
  [3] {
    [2] = new Car();
  }
  // メソッド運転
  void [4] {
    myCar.accelerate();
    myCar.accelerate();
    myCar.accelerate();
    myCar.accelerate();
    myCar.brake();
  }
  // 実行用メソッド
  public static void main(String[] args){
    // 運転者のオブジェクト生成
    Owner driver = [5] Owner();
    // 運転する
    driver.[4];
  }
}

エンジンクラスEngineを追加

Engineクラスを新たに作る。このクラスパッケージautomoblieに含まれるようにし、次の表に示すフィールドとメソッドを持つ。

項目 名前 アクセスできる範囲 役割 初期値
フィールド acceleration int 同一クラス内のみ 加速度 10
revolution 回転数 0
メソッド burn() int 同一パッケージ内のみ 燃料を燃焼し、エンジンの回転数を得る。!br回転数は現在の回転数に加速度の10倍の値を加算した値!br戻り値は回転数

// パッケージの指定
package automobile
// エンジンクラス
public class Engine {
  [1] int acceleration; // 加速度
  [1] int revolution; // 回転数
  // コンストラクタ
  public Engine() {
    acceleration = [2];
    revolution = [3];
  }
  // ガソリンを燃焼
  [4] int burn() {
    revolution += 100 * acceleration;
    return revolution;
  }
}

 Carクラスの変更

次のように変更する

// 自動車クラス
package [1];
// Carクラス
public class Car {
  [2] int speed; // スピード
  private Engine engine; // エンジン
  // コンストラクタ
  public Car() {
    speed = 0;
  }
  // エンジンの設置
  public void setEngine(Engine engine){
    this.engine = [3];
  }
  // 加速メソッド
  [4] void accelerate() {
    speed += engine.burn() / [5];
    System.out.println("Speed = " + speed + "km/h");
  }
  // 減速メソッド
  [4] void brake() {
    speed = 0;
    System.out.println("停止しました.");
  }
}

 Ownerクラス

次のように変更する

// パッケージ指定
package [1];
// auiomobileパッケージのクラスを利用できるようにする
import [2].*;
// Ownerクラス 
public class Owner {
  Car myCar; // 自動車オブジェクト名の指定
  // コンストラクタ
  [3] {
    // 自動車オブジェクトの生成
    myCar = [4] Car();
    // 自動車にエンジンの設置
    myCar.[5](new Engine());
  }
  // 運転
  public void drive() {
    myCar.accelerate();
    myCar.accelerate();
    myCar.accelerate();
    myCar.accelerate();
    myCar.brake();
  }
  // mainメソッド
  public static void main(String[] args) {
    // ドライバーオブジェクトの生成
    Onwer driver = [7] Owner();
    // 運転する
    [8].[9];
  }
}
  • クラスごとにファイル(Engine.java、Car.java、Owner.java)に保存する。
  • コンパイルに成功するとカレントディレクトリにautomobileとpersonという名前のディレクトリが作られ、その中にクラスファイル(xxx.class)が保存される。

新しいエンジンの追加

  • 新しいエンジンNAEngine、TurboEngine?NextEngine?を作り、それを搭載した自動車を作る。
  • 各エンジンはEngineクラス継承している。
  • Engineクラスの加速度accelerationは同一パッケージ継承クラスからアクセスできるように変更する。
  • NAEngineは通常のエンジンと変わらないが、TurboEngine?NextEngine?は加速度が異なり、

それぞれ、15と30である。

  • Ownerクラスは各自で考え、それぞれの自動車を運転する。

 Engineクラスの変更

// パッケージの指定
package automobile
// エンジンクラス
public class Engine {
  [1] int acceleration; // 加速度

 NAEngineクラス定義

// パッケージ指定
package [1];
// NAEngineクラス
public class NAEngine [2] Engine{
}

 TurboEngine?クラス定義

// パッケージ指定
package [1];
// TurboEngineクラス
public class TurboEngine [2] Engine {
  // コンストラクタ
  public {
    [3] = 15; // 加速度を設定
  }
}

 NextEngine?クラス定義

// パッケージ指定
package [1];
// NextEngineクラス
public class NextEngine [2] Engine {
  // コンストラクタ
  public [4]{
    [5] = 30;
  }
}

フィールドやメソッドのアクセス権
public すべてのパッケージクラスからアクセスできる
protected 同一パッケージ継承したクラスからアクセスできる
package private 同一パッケージ内のみアクセスできる
private 同一クラス内からのみアクセスできる

Carクラスを変更する必要はない

新しいエンジンを搭載した自動車の追加

新しいエンジンを搭載した自動車オブジェクトはOwnerクラスで生成する。
クラス オブジェクト
NAEngine NACar
TurboEngine? TCar
NextEngine? NCar
それぞれの自動車を4回加速し、停止させる。

自動車に「バック」と「曲がる」機能を追加

 Carクラスの変更

Carクラスに「バックする」、「曲がる」機能を追加する。

  • 「バックする」操作は自動車が停止してから実施する。if文で判定。
  • 「曲がる」操作は「曲がる方向」と「角度」を引数で指定する。
メソッド名 機能 引数
back() バックしていることを表示する なし
turn(int D int A) どの方向へどれだけ曲がったを表示する。 D 曲がる方向 0で左、1で右!brA 角度 0〜360の整数
class Car {
...
  // バックする
  public back() {
    // 停止しているかを判定
    if([1]){
      System.out.println("停止していないのでバックできません。");
    } else {
      System.out.println("バックします。");
      accelerate();
    }
  }
  // 曲がる
  public void turn(int D, int A){
    // 速度が0より大きいときに曲がれる。
    if ([2]) {
      switch([3]) {
        case 0 : System.out.println("左へ曲がります");break;
        case 1 : System.out.println("右へ曲がります");break;
        default :System.out.println("曲がれません。");;
      }
      // 角度は0〜360どのときだけ曲がれる
      if ([4]) {
        System.out.println("無理な角度です");
      } else {
        System.out.println(A + "度曲がります");
      }
    } else {
      System.out.println("止まっているので曲がれません。");
  }
}

 Ownerクラスの変更

  • driveメソッド内で入力の機能を使い、自動車を操作する。
  • どう操作すればよいかが分かるようなメニューを表示する。
  • ループを使い繰り返し入力できるようにする。
  • 「終了」動作を選択するとループを終了する。
動作 入力値 動作 入力値
加速 1 左折 4
停止 2 右折 5
バック 3 終了 9

driveメソッドを変更する。

...
// 入力に必要なクラスを含むパッケージの指定
import java.io.*;
import java.text.*;

public class Owner {
...
  public void drive() {
    String SIn; // 入力された文字列を記憶
    Number N;   // 入力された文字列の数値を記憶
    int NN = 0; // 入力された数値の整数値を記憶
    // 文字入力に必要なオブジェクトの定義
    InputStreamReader ISR = new InputStreamReader(System.in);
    BufferedReader BR = new BufferedReader(ISR);
    DecimalFormat DF = new DecimalFormat();
    // 終了を選択するまでループする
    while(NN < 9){
      // 入力を促すメッセージの表示       
      System.out.println("---------------------------------------------------");
      System.out.println("1:加速  2:停止 3:バック 4:左折 5:右折");
      System.out.println("9:終了");
      System.out.print("操作を選択 : ");
      // 入力処理
      try {
        SIn = BR.readLine();
        N = DF.parse(SIn);
        NN = N.intValue();
      }
      catch (IOException e) { SIn = "IO例外発生"; }
      catch (ParseException e){ NN = 0; }
      System.out.println("===============================================");
      // 入力値により処理を分岐
      switch(NN){
        case 1 : myCar.[1];break;
        case 2 : myCar.[2];break;
        case 3 : myCar.[2];myCar.[3];break;
        case 4 : myCar.[4];break;
        case 5 : myCar.[5];break;
        case 9 : myCar.[2];System.out.println("終わり");break;
        default : myCar.accelerate();
      }
    }
  }

  public static void main(String[] args){
    Owner driver = new Owner();
    driver.drive();
  }
}

停止したら(ブレークをかけたら)エンジンの回転数を0にする

メソッドsetZero()をエンジンクラスに追加する。このメソッドは同一パッケージ内のみでアクセスする。

 Engineクラスの変更

メソッドを追加する。

package automobile;
public class Engine {
  ...
  // 回転数を0にする
  [1] void setZero(){
    [2] = 0;
  }
}

 Carクラスの変更

ブレークをかけたら回転数を0にする。

package automobile;
public class Car {
  ...
  public void brake(){
    ...
    [1].setZero();
  }
}

スピードメータを自動車に搭載する

エンジンと同様にスピードメータのクラスSpeedMeter?を作り、そのオブジェクトを自動車のクラスが利用する。

 スピードメータの機能

項目 名前 機能 引数 アクセス範囲
メソッド getSpeed(int s) void 自動車から現在の速度を取得する 速度 同一パッケージ
displaySpeed() void 取得した速度を表示する!br(ドライバが利用するメソッド) すべて
フィールド currentSpeed int 現在のスピード。!br初期値は0 同一クラス

クラスのコードは次のようになる。

// パッケージ指定
package [1];
// クラス定義
public class [2] {
  // フィールド
  [3] int currentSpeed;
  // コンストラクタ
  SpeedMeter(){
    [4];
  }
  [5] void getSpeed(int S){
    currentSpeed = [6];
  }
  [7] void displaySpeed(){
    System.out.println("現在の速度:" + [8]);
  }
}

 Carクラスの変更

...
public class Car {
  ...
  // スピードメータオブジェクト
  [1] SpeedMeter speedMeter;
  ....
  // スピードメータの設置メソッド
  [2] void setMeter([3] sm){
    [4].[5] = sm;
  }
 // 加速メソッド
  public void accelerate(){
    ...
    // 現在の速度を取得
    [6].getSpeed([7]);
  }
  ...
}

 Ownerクラスの変更点

  • Ownerクラスのdriveメソッド内で速度を表示する(6を速度表示にする)
...
public class Owner{
  ...
  // コンストラクタ
  Owner(){
    ...
    // スピードメータの設置
    NACar.setMeter([1] [2]);
  }
  // 運転メソッド
  public void drive(){
    ...
    // 速度の表示
    case 6 : [3].[4].displaySpeed();break;
    ...
  }
  ...
}

[オブジェクト指向プログラミング]