ポリモーフィズムを体験

同じような処理

次のように乗り物の乗り方を説明するプログラムを作成しました。例えば「1:準備」を選択すると各乗り物の準備方法の説明がはじまる仕組みです。(メソッド内の処理内容は省略しています)

これからバイクの乗り方、竹馬の乗り方、H3ロケットの乗り方・・・とシリーズ化していく予定です。各シリーズのメソッドは上記のメソッド(ready、start・・)と同名にする予定ですが、処理内容が違うため共通化するのは難しいです。そのためシリーズが増えるにつれクラスが増えてしまうことになります。しかし、18行目~49行目の各シリーズ毎のメソッド呼出しが増えていくのは避けたいです。何かいい方法はないでしょうか?

複合技

いいアイディアが浮かんだ人もいるかと思います。今回は次のようにプログラムを変更しました。

まずは各シリーズのベースとなるスーパークラスVehicleを作成しました。これはabstractクラスとなっており各シリーズのクラスに同名のメソッドを強制的に作成させます。これで確実に同じ名前のメソッドが各シリーズ用意されことになります。

次にメイン処理の8行目でスーパークラスVehicleの配列をシリーズ分作成しています。

そしてスーパークラスVehicleの配列にシリーズ毎の(Bicycle、Car)インスタンスを格納します。つまり、サブクラスからスーパークラスにキャストしています。これで各シリーズのクラスを1つの配列で管理できます。

クラスが配列化されましたので、20行目~39行目の処理で、シリーズ分ループしながら各クラスのメソッドを呼び出しています。そうです、各クラス毎のメソッド呼出しを記述する必要がなくなったのです。これでシリーズが増えていってもこの部分のコードが長くなることはありません。

ポリモーフィズム(多様性/多態性)

今回のポイントはオブジェクト指向のポリモーフィズム(多様性/多態性)を利用していることです。ポリモーフィズム(多様性/多態性)とは次の通りです。(ウィキペディアより)

異なる種類のオブジェクトに同一の操作インターフェースを持たせる仕組みが多態性と呼ばれる。オブジェクト指向下の多態性は、クラスの派生関係またはオブジェクトの動的バインディングを利用した実行時変化プロセスであるサブタイピング(英語版)を指す。サブタイピング(派生法)は仮想関数(英語版)、多重ディスパッチ、動的ディスパッチ(英語版)の三手法に分類される。最もよく知られる仮想関数は多態性と同義に説明される事が多い。仮想関数は、メソッドが所属するクラスの派生関係のみに焦点を当てたシングルディスパッチであり、スーパークラス抽象メソッドへの呼び出しから、その実行時のサブクラス実装メソッドに多方向分岐させるプロセスを指す。その際はVtableと呼ばれる関数へのポインタに近い仕組みが用いられる。抽象メソッドの使用は依存性逆転の原則に準じたものであり、それを中継点にした具体的メソッドの実装は開放閉鎖の原則を体現するものである。多重ディスパッチは、メソッドが所属するクラスの派生関係に加えて、メソッドの各引数のクラスの派生関係にも注目した形態である。各引数は実行時に型ダウンキャストされて、その引数の型パターンに対応したルーチンに枝分かれする。前述の仮想関数による枝分かれがその前に入る形態もあれば、入らない形態もある。入らない場合は単一引数だとシングルディスパッチになる。多重ディスパッチの中でもプロセス分岐に関与するクラスが二つに限定されたものはダブルディスパッチと個別定義されている。動的ディスパッチは、プロトタイプベースのOOPで用いられるものであり、実行時におけるオブジェクトのメソッド参照の切り替えカスタマイズによるプロセス変化を指す。また、クラスベースのOOPでもクラスの定義内容を操作できるリフレクション機能によってこれが再現される事もある。

えーと・・・、つまり「v[i].ready();」と記述すると、同じ記述なのにbicycleクラスやcarクラスのready()メソッドが動作するのですよ、ってことです。

タイトルとURLをコピーしました