オブジェクト指向プログラミング
自動車とその所有者のクラス定義
所有者が自動車を運転することをプログラム化する。
自動車クラス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クラスの変更
次のように変更する
- Engineクラスと同様にautomobileパッケージに属する
- フィールドspeedはクラス内でのみアクセス可能にする
- エンジンのオブジェクト(engine)を持ち、クラス内でのみアクセス可能にする
- エンジンを設置するメソッドsetEngineを持つ。引数はEngineオブジェクト
- 加速、減速のメソッドはすべてのパッケージ、クラスからアクセスできる
- 速度はエンジンの回転数の1/100を現在の速度に加算する
// 自動車クラス 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 |
自動車に「バック」と「曲がる」機能を追加
Carクラスの変更
Carクラスに「バックする」、「曲がる」機能を追加する。
メソッド名 | 機能 | 引数 | |
---|---|---|---|
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クラスの変更
- 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; ... } ... }