在doStuff()的代碼裡,最讓人吃驚的是盡管我們沒作出任何特殊指示,采取的操作也是完全正確和恰當的。我們知道,為Circle調用draw()時執行的代碼與為一個Square或Line調用draw()時執行的代碼是不同的。但在將draw()消息發給一個匿名Shape時,根據Shape句柄當時連接的實際類型,會相應地采取正確的操作。這當然令人驚訝,因為當Java編譯器為doStuff()編譯代碼時,它並不知道自己要操作的准確類型是什麼。盡管我們確實可以保證最終會為Shape調用erase(),為Shape調用draw(),但並不能保證為特定的Circle,Square或者Line調用什麼。然而最後采取的操作同樣是正確的,這是怎麼做到的呢?
將一條消息發給對象時,如果並不知道對方的具體類型是什麼,但采取的行動同樣是正確的,這種情況就叫作“多形性”(Polymorphism)。對面向對象的程序設計語言來說,它們用以實現多形性的方法叫作“動態綁定”。編譯器和運行期系統會負責對所有細節的控制;我們只需知道會發生什麼事情,而且更重要的是,如何利用它幫助自己設計程序。
有些語言要求我們用一個特殊的關鍵字來允許動態綁定。在C++中,這個關鍵字是virtual。在Java中,我們則完全不必記住添加一個關鍵字,因為函數的動態綁定是自動進行的。所以在將一條消息發給對象時,我們完全可以肯定對象會采取正確的行動,即使其中涉及上溯造型之類的處理。