[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[jfriends:00501] Re: 型情報によるディスパッチ ( に似たもの) がメソッドオーバーロードで実現できない理由 ? (Re: Java プログラマーのための Perl 入門 ?)



前橋です。

yasuyuki@xxxxxxxxxxxx さんは書きました:
>> クロージャーと何の関係が?
>他の言語は知りませんが、
>Scheme では lambda があればオブジェクト指向システムが実現できます。

まあ最低限連想配列とクロージャーがあれば、オブジェクト指向システムを
実現することは可能ですけど(ただしそれはクラスベースのオブジェクト指向には
ならないと思いますが)。

しかしそれは、オブジェクトの連想配列(メソッドテーブル)に依存するわけですから、
引数の型に合わせたディスパッチは難しそうですし、ディスパッチを行わない
「"Javaのメソッドオーバーロード"相当のこと」も、ちと難しそうな気がします。
Schemaの例は私は知りませんけど。

>> Shape[] shapes;
>
>やっと分かりました。
>
>親の型の配列に入っているから「ディスパッチ」されない、
>ということですね?

そういうことです。足掛け2世紀にわたる勘違いが解消されたことを
お祝いいたします。

>結局、個々の Shape サブクラス型オブジェクトに"型タグ"みたいなものを
>付けておき、ディスパッチの仕組みを自前で書くしかないのですね。

まずJavaでは、各オブジェクトに「型タグ」は最初から入っていて、
instanceofで確認できます。だから自前でディスパッチするなら、else ifを
延々と書いて、instanceofで型を調べることになります。

だから、5年以上前、我々は、こういう議論をしていたわけです。

http://www.javaopen.org/jfriends/mlarchive/msg02354.html
前橋wrote:
| だからといって、drawをShape以外の所に置いてしまうと、
| 
| ・いざ描画するときには、長〜いelse ifの連なりで、いちいち
|   instanceofでクラスを調べるの?
| ということになっちゃいます。これはこれで悲し過ぎます。

それに対するえんどうさんの回答がこうだったわけで。

http://www.javaopen.org/jfriends/mlarchive/msg02360.html
えんどうさん wrote:
| メソッド・オーバーライドを使って区別するのかもしれません。

ほら通じてない。

>どういうツッコミが入るか想像がつきますが、とりあえず書きました。

というわけで予想通りのツッコミだと思うのですが、Shapeにdraw()
メソッドを付けるのなら最初から苦労はないのです。
Javaは、メソッドを呼ぶ対象のオブジェクトの型によるディスパッチ機能は
最初から備えています。引数の型によるディスパッチ機能はないですが。

もし、引数の型により、

DisplayManager.draw(Point);
DisplayManager.draw(Line);
DisplayManager.draw(Circle);

を実行時に呼び分けてくれるのなら、このケースではそりゃ便利でしょう。
CLOSではそれはできるけど、Javaではできない。だから、機能と用途が
違うと言っているのです。

んで、どうせ実行時に呼び分けてくれないのなら、こんなのは

DisplayManager.drawPoint(Point);
DisplayManager.drawLine(Line);
DisplayManager.drawCircle(Circle);

と書いたって実質影響がないし、実際、Javaのメソッドオーバーロードは、
メソッド名をこんな感じで裏でこっそり付け直す機構以上のものではありません。

------------------------------------------------------------
  前橋 和弥                        PXU00211@xxxxxxxxxxx
                                   http://kmaebashi.com
------------------------------------------------------------