l

2012年1月27日 星期五

什麼是物件導向(3):Polymorphism

January 26 23:01~January 27 00:23

Polymorphism,中文翻譯成「多形」,說真的這個概念當年Teddy學OO的時候搞了好久才弄懂,後來看了「課本」的定義之後,覺得寫得還滿好的,請參考Object-Oriented Software Engineering: A  Use Case Driven Approach第55頁:

Polymorphism means that the sender of a stimulus does not need to know the receiving instance’s class. The receiving instance can belogin to an arbitrary class.

再看一下55頁中另一段類似的解釋

If an instance sends a stimulus to another instance, but does not have to be aware of which class the receiving instance belongs to, we say that we have polymorphism.

翻成白話文就是說:一個訊息(message or event or stimulus)的意義是由接收者(接收到這個訊息的物件)來解釋,而不是由訊息發出者(sender)來解釋。所以,在runtime時只要接受者換成不同的物件或是instance,系統的行為就會改變。具有這樣的特性就稱之為polymorphism。還是不懂,對,很正常。不過在看一個活生生的例子鄉民們就應該懂了。

***

Teddy(sender,等一下準備送出信息的物件)走在路上看到前方有兩位名人,分別是「林志玲」與「阿美姐」(等一下準備接收訊息的兩個物件),於是大喊一聲「美女請留步(訊息)」。理論上Teddy期待只有「林志玲」會「回頭」(訊息接收者的行為),沒想到「阿美姐」也回頭了...XD。所以說,一個訊息的解釋是由接收者來決定的,而不是送出者。如果一個系統具有這樣的特性,那麼我們就說這個系統具備多型的行為。

舉個程式的例子:

List<String> list = new LinkedList<String>();

list.add(“This is a book”);

從上面這一行程式來看,我們可以說寫程式的人送了一個add這個訊息給list這個instance。從靜態程式碼來看,鄉民們一定知道list.add(“This is a book”)的行為,但是如果list這個instance不是像上面程式一樣寫死new LinkedList<String>();,而是runtime時傳入的任意符合List介面的某個instance,那麼程式的行為就無法只從靜態的程式碼得知了,而且add(“This is a book”);訊息的解釋也只能看runtime時list instance指到哪一個instance而定。

***

一般常用的靜態型別程式語言例如Java、C#,要做到polymorphism必須透過繼承,不管是implementation inheritance或是interface inheritance。有些動態型別程式語言,如果Teddy沒記錯的話像是Smalltalk(如果有錯請留言或來信幫忙更正),可以不需要靠繼承來達到polymorphism,但是在runtime如果接收者沒有支援某個訊息的話,則是會出現runtime errors。

總之,其實Teddy想講的重點是,這些老外厲害的地方,就是可以用很簡短的句子寫出某些觀念或是名詞的定義。因為除非真正了解所要描述的觀念或是名詞,否則是無法寫出這樣的定義出來。當年Teddy背下這個定義(因為考試會考啊…Orz)到現在都還依稀記得。什麼,你問Teddy記下這些定義有何用 ?Teddy也說不上來,也許哪一天鄉民們去面試不小心考了polymorphism這一題,而鄉民們恰巧看到這篇文章所以把書中的定義給寫了出來,但是主考者可能看不懂...Orz。不過這都不是重點,就以「純欣賞」的角度為能夠寫出這麼精簡定義的作者們拍拍手就好了...XD。

***

友藏內心獨白:這幾天好冷,寫到手都凍僵了。

3 則留言:

  1. 這樣說,不知合不合適?

    多形就是:同一個介面下,於不同實作中定義多型之方法,使得操作不同實作的物件者不用關心是哪個實作實體,只要操作共同之介面就能正確地行為。

    這樣是很實際說到:為什麼要多型這回事
    不過還不夠general....

    或者說,它是種期待,期待發出端只要知道傳送什麼msg,而由接收者來作不同的處理
    以這種特性去作的語言還有一個:Obj C,它幾乎都是用msg去傳遞的,反倒是C++的多型有點綁太多了

    回覆刪除
  2. SUPERSUPERSUPERSUPERSUPERSUPER MAN2012年1月27日 上午1:26

    更直接點講,多形就是希望:使用不同實作之物件時,使用統一的訊息傳遞介面,完全不用操心實作之細節差異
    這和希望把一切細節都包進黑盒子的事,是有著異曲同工之妙,但一個強調:資料細節解藕及資料保護等等,多型則是強調:只要有統一的介面,就不用擔心對於不同實作的操作

    也就是說,把處理判斷交給實作之實體,那麼可以少去switch及主程式與特定class的coupling,此外還能讓符合規格的物件能夠作一模一樣的操作而不用改寫,也就是:
    runtime智慧化處理之模型

    我個人覺得當初想到多型概念的人,大概心裡在想這個吧?:P

    回覆刪除
  3. 有沒有實際的例子, 讓我們看看多型到底有多行?^^

    回覆刪除