……
大B:“要求能訪問到每個類的對應的方法。我們第一反應應該是這樣的。”
((PA)obj).runPA;
((PB)obj).runPB;
((PC)obj).runPC;
((PD)obj).runPD;
((PE)obj).runPE;
大B:“當數目變多的時候,維護ifelse是個費力氣的事情:仔細分析if,else做的工作,首先判斷類型,然後根據類型執行相應的函數。”
小A:“如何才能解決這兩個問題呢?”
大B:“首先想到的是Java的多態,多態就是根據參數執行相應的內容,能很容易的解決第二個問題,我們可以寫這樣一個類。”
大B:“這樣隻要調用run方法,傳入對應的參數就能執行了。”
小A:“還有一個問題就是判斷類型。”
大B:“由於重載(overloading)是靜態多分配。Java語言本身是支持‘靜態多分配’的。所以造成重載隻根據傳入對象的定義類型,而不是實際的類型,所以必須在傳入前就確定類型,這可是個難的問題,因為在容器中對象全是Object,出來後要是判斷是什麼類型必須用if(xxinstanceofxxx)這種方法。”
小A:“如果用這種方法豈不是又回到了原點,有沒有什麼更好的辦法呢?我們知道Java還有另外一個特點,覆寫(overriding),而覆寫是‘動態單分配’的,那如何利用這個來實現呢?”
大B:“看下邊這個方法:我們讓上邊的一些類PA、PB、PC、PD、PE都實現一個接口P,加入一個方法,accept。”
//把自己傳入。
然後在visitor中加入一個方法
//把自己傳入。
//這樣你在遍曆中可以這樣寫
大B:“首先執行的是‘把自己傳入2’,在這裏由於Java的特性,實際執行的是子類的accept,也就是實際類的accept然後是‘把自己傳入1’,在這裏再次把this傳入,就明確類型,OK我們巧妙的利用overriding解決了這個問題。其實歸納一下第二部分,一個關鍵點是‘自己認識自己’,是不是很可笑。”
(本章完)