多型
介紹多型的觀念及程式基本撰寫方式。
何謂多型? What is Polymorphism?
多型 Polymorphism 一詞是指生物學中一個生物或物種可以有不同的形式或階段。 在物件導向程式設計的概念中,利用父類別提供的方法呼叫,子類別可以有自己特有的行為。
舉個例子:
還記得繼承關係可以用『is a』來表述嗎? 我可以說 Dog is a Animal. 或 Bird is a Animal. 或 Fish is a Animal. 這是OK且符合邏輯的。
好,那現在我有4隻動物,是什麼動物不管,我就把牠們都當成動物就好。 我知道動物裡面有一個move()的方法,我讓每隻動物都使用這個move()的方法。
程式如下:
變數a看起來OK,宣告是Animal且也用Animal的建構子去初始化。
變數b看起來就怪怪的,用Dog()來初始化的話不是應該宣告成Dog型態嗎? 是的,那樣寫也OK,我們知道依據繼承關係,『Dog is a Animal.』所以我這樣寫也並非違反邏輯。 利用Dog()建構子創造的物件,理當擁有Dog類別定義的所有成員,但不管,現在我們只把這個物件當作Animal來看。
變數c,不管你怎麼建構你的物件,我都會用Animal的角度去看你。
變數d:本體是Fish,但有人把我當成動物。 (變數b,c,d是差不多情況)
好,現在我不管牠們4個的『本質』是什麼,我只知道我把牠們都當做 Animal 來看,而我知道 Animal 裡面有定義一個方法叫做 move(),所以把4隻Animal的move()都呼叫看看。
執行結果:
可以看到,雖然都宣告為 Animal,也都呼叫了Animal裡面的move()方法,但每個物件表現出來的都不一樣,因為他們的『本質』不一樣。
這就是多型 Polymorphism 的簡單範例。
從上面的例子可以看出,我們只要管他是不是動物就好,不用管他的本質是什麼 ,就可以對他進行處理。
只要可以視為Animal的物件,就可以使用這個方法而不會出錯。 這樣的設計方式可以降低方法定義對類別的依賴,使用一個制定好的介面,利用該介面來操作不同的物件,增加程式的彈性及可維護性,設計上也比較有架構。
如果沒有多型的話,
要設計一個方法用來呼叫 Animal、Dog、Bird、Fish的移動move()方法,會變成這樣:
在有多型的情況下,我知道Dog、Bird、Fish都可以被當成Animal,而我們要呼叫的move()也剛好有被定義在Animal中,所以只需要制定一個可以操作Animal這個介面的方法就好。
使用這個方法,就可以對所有『可以被當成Animal的物件』進行操作:
執行結果:
隱性轉型 Implicit Casting
在上面程式中,我們定義了moveAnimal(Animal ani)的方法,他會接受一個Animal參數進來,但程式中我們卻給他Dog、Bird、Fish這些類別的物件,為什麼能動?
因為Java會幫你進行型態轉換,子類別必定擁有母類別的所有屬性、所有方法,所以子類別一定可以轉型為母類別,而不會出錯。
因為這個機制,所以搭配多型的設計方法,程式撰寫上變得非常便利。
轉型失敗 Casting Fail
我們知道利用小括號裡面放型態可以進行強制型態轉換,但會不會有問題?
以繼承來說,子類別是母類別的『延伸』,所以子類別轉型成母類別是絕對OK的,因為擁有母類別的所有欄位、所有方法。 但若母類別轉型成子類別呢?
範例程式:(Dog 繼承 Animal)
執行結果:
沒錯,執行的時候發生了錯誤,產生ClassCastExeption例外。
強制轉型要付出的代價是工程師自己要負責的,以上述程式來說,『編譯會過,執行會錯』,因為母類別不一定擁有子類別的欄位,所以不能這樣轉換。
Last updated