OO中使系統能具備彈性跟動態擴充的利器:Polymorphism(多型)。多型色是OO四大特色中對初學者而言較為抽象的概念,簡單來說多型只是想延後function binding的時間,等到執行時期才決定要呼叫哪一個function。如此,可使程式的執行不在於編譯時期決定,而延後到執行期間才動態決定呼叫何者。例如:編譯時期只定義動物有一個walk() function,而在執行期間若為獅子那就動態呼叫獅子此類別的walk() function;反之若為人那就動態呼叫人此類別的walk() function。
就定義面而言多型大多定義如下:將相同的訊息傳遞給不同的物件,進而引發出不同的行為反應。而就程式面的實做部分,我常將多型定義如下:
l 利用父類別的型態
l 接受子類別的物件
l 做相同的動作
l 引發不同的行為
It’s show time,請鼓掌馬戲團表演來囉!請試想今天你要寫一個馬戲團的表演程式,若一開始我們只有收到各個動物出場時rundown如下:先走一圈、再發出叫聲、最後逃過火圈。但就是有哪些動物根本還不曉得,以傳統的程式語言會變的綁手綁腳沒辦法實際撰寫。在OO中可就奇妙了,我們只要將這些抽象化的概念定義成抽象類別或介面即可,我們開始定義出動物這個類別,並且定義出三個抽象方法walk()、barking()以及jump(),記住:在多型中我們需先規範出之後各類別需要遵守的規範即可。需正式上場的動物如狗、貓、豬、老虎…等,需各自將上述定義的抽象類別、介面繼承並將walk()、barking()以及jump()實做。之後我們可以加上一個method如下:
public void show(Animal a) {
a.walk();
a.barking();
a.jump();
}
請注意以後只要:
Tiger t = new Tiger;
Show(t); à這樣就會變成老虎走路、發出叫聲、最後跳火圈囉
以此類推每種動物都可以這樣產生實體(instance),之後就開始呼叫show(instance)à恭喜此instance就會開始呼叫的自己對應的walk()、barking()跟jump()。可見多型可以使程式在利用的程度在攀升,另外當有新動物(newa)加入時,只要他乖乖的去繼承抽象類別,並將屬於自己的walk、barking、jump等動作定義完,之後請呼叫show(newa)à嘖嘖,馬上就換這個新動物newa開始做walk、barking、jump等動作了。因為show都不需更動因此如果有新的動物加入在執行期間動態呼叫他,皆可以馬上動態繫結到此一動物本身所定義的方法,因此彈性極高。設計師也不用在因為名單未定就無法在compile time下決定了!
My goodness!rundown變了。原本是先走、再叫、最後跳,但現在想要先叫、再走、最後跳,如果是善用多型的人一定會想說:哈終於等到這一天囉…XD,一切的改變只有上層邏輯程式需更動,其餘的類別程式完全不用改變。see it,show此一方法將變成如下程式碼。
public void show(Animal a) {
a.barking();
a.walk();
a.jump();
}
記住多型的起手勢:『Inheritance』 +『Overriding』+『Upcasting』。多型伴隨著一定是有父子類別的關係,或介面跟實做的關係,藉由overriding子類別會將父類別的方法重新定義來符合自身所需;另一方面,我們會針對上層的抽象類別或介面來撰寫邏輯上的運作,避免這些邏輯運作跟實體的子類別產生關聯,如此對日後的維護將有大大的幫助,以上述的馬戲團為例:show()這個函式都是針對上層提供的方法來操作,但於執行期間系統會自動依據他所接收的Animal a此一物件所屬的類別來動態繫結show當中各邏輯運作所應該對應的方法為何。
勵行簡單藝術。善用多型可使程式碼所需大幅簡化、在利用性也可提升,當然可以將原本static time進行binding的函式展延到dynamic binding。好的程式設計師不應該是寫出複雜的程式,而是後人易於維護跟簡潔易懂的程式。
複雜是工程、簡潔是藝術,歷史上偉大的藝術是非常值錢的…XD。
留言列表