![]() |
[1999 年 2 月号] |
[Happy Squeaking!!]
5.ポリモルフィズム
5.1 多様性、多相性、多態性
「ポリモルフィズム」聞きなれない言葉です。ギリシャ起原の英語で、「多様の (poly)」と「形態をもっている状態(morphism)」の合成語です。オブジェクト指向を解説する日本語の書籍でも、この言葉は「多様性」、「多相性」、「多態性」いった様々な訳がされており、定まっていません。原語にせよ訳語にせよ言葉だけきくと非常に難しそうですが、内容は実はたいしたことはありません。
例えば、犬であるポチと、カンガルーであるパンチに対して、「走れ」と命じた場合、ポチも、パンチも、それぞれ「犬らしい」もしくは「カンガルーらしい」走り方で走ることになります。つまり、同一のメッセージ「走れ」に対して、それを受け取った側が、自分自身のクラスに記述されている「走り方」(メソッド)に従って、独自の動作をし、多様な振る舞いを見せることを指します。
以上がポリモルフィズムの説明です。非常に単純なことなので拍子抜けしてしまうほどです。
ただし、単純だからといって侮ってはいけません。この単純さこそが、ポリモルフィズムのパワーの源となっているのです。
オブジェクト指向の理想的な姿は、オブジェクトがそれぞれインテリジェントな実体として存在し、それらに対し、単にメッセージを送りさえすれば処理が行われるというものです。ポリモルフィズムは、このような姿の実現に役立つことになります。つまり、送る側が、複雑な部分を一切考慮せずに、「よきにはからえ」的な画一的メッセージを送れば、後は受け捕り側のオブジェクトでそれぞれが別個の多様な動作を行い、複雑な仕事をこなすわけです。
具体的に、疑似コードの例で示してみましょう。
例えば高速道路のゲート通過の際に車両に応じて料金を計算するシステムを開発していたとします。
トラックと乗用車、バイクでは、それぞれ料金の計算の仕方が変わってきます。この場合、計算結果を取り出す側(システムを使う側、以後クライアント側といいます)では、ポリモルフィズムが使えなければ以下のようなコードを強いられます。
//クライアント側 (ポリモルフィズムが使えない場合) calculate() { Vehicle v := Gate.getVehicle(); //乗り物が取り出されるとする Result ret; //計算結果の入る変数 Type type := v.getType(); //乗り物がなにかわかるようにタイプを取り出す。 If (type == 'Truck') { ret := caluculateTrackOf( v ); //トラック用計算 } elseif ( type == 'Car' ){ ret := caluculateCarOf( v ); //乗用車用計算 } elseif ( type == 'Bike' ) { ret := caluculateBikeOf( v ); //バイク用計算 } }
なんとも手続き的です。クライアント側は乗り物の種類に応じて計算結果をif文によって振り分けてあげることになります。
さらに乗り物の種類が新たに増えた場合(例えばBusが追加される)、クライアント側では、対応するif文を付け加えてあげなければなりません。
しかし仮に以下のようにクラスの継承関係が作られていたとします。
Vehicle Truck Car Bike
(Vehicleの下にTrack,Car,Bikeサブクラスが定義されている)。
そしてVehicleのサブクラスで独自の計算をするcalculate()操作の定義を行っていたとしたらどうでしょう。
この場合、クライアント側は、ポリモルフィズムを利用して以下のように記述することができます。
//クライアント側 (ポリモルフィズムが使える場合) calculate(){ Vehicle v := Gate.getVehicle(); //乗り物が取り出されるとする Result ret; //計算結果の入る変数 ret := v.calculate(); // 「計算して」と頼むのみ }
クライアント側の煩わしい世話やき部分(if文、if文の連続で処理を分ける)が消滅し、コード量が激減しています。
また、仮にBusが新たな乗り物として追加されたとしてもクライアント側では一切の変更の必要がありません。
継承は、メソッドの差分定義などによりクラスを提供する側のコードの再利用性を高めます。
一方で、ポリモルフィズムは、クラスを利用する側(クライアント側)のコードの再利用性を高めることになります。呼び出される側の変更の影響を受けにくくなり、クライアント側のコードはより長き時間、場面において使われていくことになります。
© 1999-2001 OGIS-RI Co., Ltd. |
|