前も同じようなタイトルで書きましたが、
多重ディスパッチ
http://d.hatena.ne.jp/nishiohirokazu/20080304/1204604699 にあった内容。スクリプト言語でプログラミングするようになってから、 この手の、「あれ?これ出来なかったんだっけぇ?!」 というシチュエーションが良くある。
記事内のオーバーロードしたメソッドが 実行時の型によって選ばれないという件。
昔は気にならなかったのは、多分できないのが、 当たり前だという脳回路が出来上がっていたんだと思う。
普通は感じる事ができないし、出来ないからこそ 恐ろしい「思考停止」という状態を 過去の自分に感じる事ができた。
これは貴重な体験だ。
それは置いておいて、
記事内の現象自体は、Javaはインタフェースに対して メッセージングをするという概念で考えれば、 納得できるが、それでは、やはり思考停止だと思い、 今の自分だったらどう実装するだとうという観点で 考えてみた。
Java的には、 Animalにenterメソッドをつける方法が一番 エレガントな気がするけど、 やりたい事がシンプルに書けてない感じが残る
(この感じがスクリプト言語から得た感覚なのかも。。)
結局今の自分なら以下のように書くかなぁという 内容です。
import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; public class TestMultiDispatch { public static void main(String[] args) { Zoo z = new Zoo(); for( Animal a : new Animal[]{new Cat(), new Dog(), new Cat()}){ z.enter(a); a.say(); } } } class Zoo{ Hashtable h = new Hashtable(); public Zoo() { h.put(Dog.class, new ArrayListなんか主旨とズレてるけど。()); h.put(Cat.class, new ArrayList ()); } public void enter(Animal a){ List list = (ArrayList)h.get(a.getClass()); list.add( a ); } } abstract class Animal{ abstract public void say(); } class Cat extends Animal{ public void say(){ System.out.println("にゃ〜"); } } class Dog extends Animal{ public void say(){ System.out.println("わん!"); } }