1. 多態(tài)的定義
多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力兼贸。在JAVA中,多態(tài)通過在子類中重寫父類方法去實現(xiàn)坷牛。但是在JS中很澄,由于JS本身是動態(tài)的颜及,天生就支持多態(tài)。大家可以通過幾個例子來理解一下讯蒲。
2. 多態(tài)的實現(xiàn)
舉個例子吧肄扎,國王聽膩了只有鴨子為他唱歌,他決定搞一個動物合唱團犯祠。所以,大臣們搜羅了鴨搔耕,雞痰娱,狗等動物,而且還設置了專門的選拔官員測試鲸睛,選拔官員一聲令下:‘唱’坡贺,面前的動物就發(fā)出了特有的叫聲,鴨子嘎嘎嘎钧萍,小雞咯咯咯政鼠,小狗汪汪汪......要實現(xiàn)這個功能,我們可以使用如下代碼:
var singStart(animal){
if (animal instanceof Duck) {
console.log('嘎嘎嘎');
} else if (animal instanceof Chicken) {
console.log('咯咯咯');
}
function Duck(){}
function Chicken(){}
singStart(new Duck()); // 嘎嘎嘎
singStart(new Chicken()); // 咯咯咯
}
這種方法當然也可以實現(xiàn)多態(tài)万搔,但是卻違反了封裝性,我們將可變的動物類型與不可變的唱歌指令耦合到了一起瞬雹。如果動物類型增加,我們必須在開始唱歌方法中新增判斷分支呢诬。這就好比是選拔官員發(fā)出的指令是這樣的:“你是鴨子的話胖缤,唱嘎嘎嘎哪廓,是雞的話狗唉,唱咯咯咯分俯,是狗的話缸剪,唱汪汪汪......”這明顯是不合理的。真實的情況應該是橄登,選拔官員發(fā)出簡短清晰的指令“唱”時讥此,每種動物會場出自己獨有的聲音。
讓我們用面向?qū)ο蟮乃枷肴タ紤]卒稳,將不變的指令隔離開來,將可變的具體實現(xiàn)封裝起來充坑。JAVA會使用類繼承和重寫的方式來實現(xiàn)染突,如下:
abstract class Animal {
abstract void sing();
}
class Duck extends Animal {
public void sing() {
System.out.println("嘎嘎嘎");
}
}
class Chicken extends Animal {
public void sing() {
System.out.println("咯咯咯");
}
}
public class Test {
public static void main(String[] args) {
Animal duck = new Duck();
Animal chicken = new Chicken();
singStart(duck); // 嘎嘎嘎
singStart(chicken); // 咯咯咯
}
public static void singStart(Animal a) {
a.sing();
}
而對于JS來講份企,我們?yōu)榫唧w的動物類型的原型定義具體的sing方法即可,如下:
function Duck(){}
Duck.prototype.sing = function(){
console.log('嘎嘎嘎');
}
function Chicken(){}
Chicken.protorype.sing = function(){
console.log(‘咯咯咯’);
}
function singStart(animal){
animal.sing();
}
singStart(new Duck()); // 嘎嘎嘎
singStart(new Chicken()); // 咯咯咯
而且司志,更棒的是,JS是動態(tài)的囚霸,這里并不限制傳入的參數(shù)類型是animal。大家可以看到额嘿,我們在代碼中吨述,也沒有實現(xiàn)Animal這個類型,事實上,我們可以傳入任意類型的對象冰啃,只要它正確包含一個sing方法即可阎毅。如下:
function Person(){}
Person.protorype.sing = function(){
console.log(‘哈哈哈’);
}
singStart(new Person()); // 哈哈哈
可以看出來,在JS中實現(xiàn)多態(tài)更加方便扇调,且更加強大。
參考
BOOK-《JavaScript設計模式與開發(fā)實踐》 第一部分
Javascript基于對象三大特征
【原生js】js面向?qū)ο笕筇卣髦鄳B(tài)筆記
JAVA多態(tài)