抽象クラスを使用してポリモーフィズムを実現させてみましょう。スーパークラスの型でサブクラスのオブジェクトを扱えることを思い出してください。抽象クラスの型で、抽象クラスを実装したオブジェクトを格納することができます。ただしその場合、呼び出すことができるのは抽象クラスで定義しているメンバだけです。
これからいろいろな乗り物を操作できるシミュレーターを作成してみましょう。乗り物クラスを継承したスポーツカークラス、タクシークラスを作成して利用してみましょう。ポリモーフィズムを確認するために、乗り物のテストをするテストドライバークラスを作成して、テストドライバーが乗り物を動かすようにします。
○ プロジェクト
プロジェクトを作成して確認してみましょう。
プロジェクトの種類 | コンソール アプリケーション |
---|---|
プロジェクト名 | AbstractPlymoTest |
○ 作成の準備
「AbstructClassTest」プロジェクトを修正して作成しましょう。AbstructClassTestフォルダーをコピーして、作成するプロジェクト名にフォルダー名を変更してください。
○ プログラム
次に、乗り物クラスを継承したタクシークラスを作成しましょう。
Taxi.vb
○ クラス図
○ 解説
4行目では最大スピードを格納するフィールドを定義しています。インスタンス生成時に最大スピードを初期化し、加速するときにこのフィールドを参照して加速するかを決定します。
7~9行目では売上金、走行距離、乗車状態のプロパティを定義しています。
12~19行目ではコンストラクタを定義しています。このコンストラクタはガソリン量を受けとって、スーパークラスのコンストラクタを呼び出し、ガソリン量をセットしています。そのあと、ガソリンタンク容量と比較して、セットしたガソリン量が多ければ最大容量にセットするという処理をします。
22~34行目ではSpeedUpメソッドをオーバーライドしています。抽象クラスを継承すると、抽象メソッドは必ずオーバーライドしなければならないという義務が発生します。今回は加速するときに、消費するガソリン量がない場合は加速しない、最大スピードに達していた場合はそれよりスピードが出ないようにしています。 スポーツカークラスと違い、消費する燃料を抑えています。
36~52行目では乗車する処理を定義しています。車が走っているか、既に乗車している場合には人は乗せられないようにしています。止まっているか、空車の場合は引数として受け取った料金、距離、乗車状況を、プロパティを使って設定しています。
54~68行目では、降車する処理を定義しています。車が走っている場合は人を降ろせないようにしています。止まっていれば降車処理をしますが、今回は乗車状態を変更しています。
○ プログラム
次に、乗り物を運転するテストドライバークラスを作成しましょう。次にようにクラスを作成してください。
TestDriver.vb
○ クラス図
○ 解説
3行目では加速度合いを保存する変数を宣言しています。また、4行目ではテストドライバーが操作する乗り物オブジェクトを保持する変数を宣言しています。この変数はVehicle型なので、Vehcileを継承したクラスであれば保持できることになります。そのためテストドライバーは乗り物を継承した様々なタイプの乗り物を動かすことができます。今回作成したタクシークラスと、先回作成したスポーツカークラスはVehicleクラスを継承しているため、保持することができます。
7~10行目ではコンストラクタが定義されています。引数に乗り物、加速度合いを受け取り、それぞれのフィールドにセットします。テストドライバーがどの乗り物を運転するかがテストドライバーオブジェクトを作るときに決まることになります。
13~15行目では加速処理が定義されています。ここのSpeedUpメソッドは、乗り物クラス・スポーツカークラス・タクシークラスとは直接関係はありません。そのため、別のメソッド名で定義しても問題ありません。自分が乗っている(フィールドに保持している)乗り物のSpeedUpメソッドを呼び出す記述が14行目にあります。フィールド変数にセットされているスピード分だけ加速します。
17~19行目では減速処理が定義されています。ここのSpeedDownメソッドは、乗り物クラス・スポーツカークラス・タクシークラスとは直接関係はありません。そのため、別のメソッド名で定義しても問題ありません。ここでの振る舞いは、前述したSpeedUpメソッドと同じです。自分が乗っている(フィールドに保持している)乗り物を減速させます。
○ プログラム
では次にMainメソッドを修正しましょう。
Module1.vb
○ 解説
15~17 行目で、乗り物の選択肢を用意しました。ユーザーはスポーツカーかタクシーを選ぶことになります。22~34行目では、選択した乗り物と、テストドライバーを生成しています。乗り物に応じてテストドライバーに加速の仕方を指示(乗り物と加速度合い)しています。
39~60行目では、メニューを表示してテストドライバーに加速、減速などの指示を与えています。テストドライバーは自分にセットされている乗り物に対してSpeedUpメソッドやSpeedDownメソッドを呼び出して車を走らせることになります。その状態をShowMeterメソッドで表示しています。スポーツカーかタクシーのどちらのSpeedUp・SpeedDownメソッドが呼び出されるかは、テストドライバーにどちらのオブジェクトがセットされているかによって決まります。
抽象クラスを使用してポリモーフィズムを実現させることができました。各オブジェクトを作り、テストドライバーにテスト実行時に乗り物を指定して加速させたり減速させたりさせ、その乗り物の状態を確認してメーターに表示しています。TestDriverクラスで呼び出しているSpeedUpメソッドやSpeedDownメソッドは、どのオブジェクトがセットされるかによって振る舞いが変わっているのを確認できたと思います。これを多態性、多様性(ポリモーフィズム)と言います。
抽象クラスでは同じような属性を持ったオブジェクトを作ることができます。乗り物クラスであれば、乗り物の部類に属するものを定義することができます。次に、属性が全く異なるものに対しても同じ処理を指定する方法を見てみましょう。