在上一篇javascript繼承—prototype最優兩種繼承(空函數和循環拷貝)(3) ,介紹了js較完美繼承的兩種實現方案,那么下面來探討一下js里是否有多繼承,如何實現多繼承。在這里可以看看java是如何處理多繼承的問題,java里是沒有多繼承的,即一個子類不能同時繼承多個父類,但可以實現多個接口,這也間接的實現了多繼承。主要是因為多繼承涉及到成員變量重名的問題,對於java這種強類型語言,是很不好操作的。所以java讓接口成的成員變量只能定義為常量。這也解決了實現多個接口的問題。
對於js來說,如何實現一個子類繼承多個父類呢?怎樣讓父類的特權屬性和共有方法實現比較完美的繼承呢?參考上一篇中的兩種繼承方式。會發現多繼承是不能用空函數來實現的,下面具體說明如何操作。
function Parent1(name,age){ this.name = name; this.age = age; this.height=180; } Parent1.prototype.say = function(){ alert('hi...'); } function Parent2(name,age,weight){ this.name = name; this.age = age; this.weight = weight; this.height = 170; this.skin='yellow'; } Parent2.prototype.walk = function(){ alert('walk...'); } function Child(name,age,weight){ Parent1.call(this,name,age); Parent2.call(this,name,age,weight); } for(var i in Parent1.prototype){Child.prototype[i] = Parent1.prototype[i]} for(var i in Parent2.prototype){Child.prototype[i] = Parent2.prototype[i]} var c1 = new Child('xiaoming',10,8); console.log(c1); //Child { name="xiaoming", age=10, height=170, 更多...}
console.log(c1.constructor);//Child(name,age,weight)
可以看到子類Child的實例c1打出的結果繼承了父類的所有屬性和方法。當然這里存在一個問題,如果父類Parent1和Parent2都有name這個屬性的時候,會以后繼承的為主。即這里c1的name屬性為170,覆蓋了Parent1的屬性180。
可以理解javascript的多繼承其實就是前面介紹的js循環拷貝繼承的多次使用。下面來講講為什么空函數繼承的方法是不行的。同樣舉例說明:
二、用空函數實現多繼承(此方法不行)
function Parent1(name,age){ this.name = name; this.age = age; this.height=180; } Parent1.prototype.say = function(){ alert('hi...'); } function Parent2(name,age,weight){ this.name = name; this.age = age; this.weight = weight; this.height = 170; this.skin='yellow'; } Parent2.prototype.walk = function(){ alert('walk...'); } function Child(name,age,weight){ Parent1.call(this,name,age); Parent2.call(this,name,age,weight); } function Empty1(){} Empty1.prototype = Parent1.prototype;//將Parent1的prototype賦給Empty1的prototype Child.prototype = new Empty1(); //將Empty1的實例賦給Child的prototype //同樣對於Parent2也使用這種方法時 function Empty2(){} Empty2.prototype = Parent2.prototype; Child.prototype = new Empty2(); //這里Child的prototype已經有了Parent1的共有方法,這里將Parent2的方法賦過來,是覆蓋 Child.prototype.constructor = Child; var c1 = new Child('xiaoming',10,8); console.log(c1.constructor);//Child(name,age,weight) console.log(c1); //Child { name="xiaoming", age=10, height=170, 更多...}
![age_thumb[4] age_thumb[4]](/image/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNTAyNTQ4LzIwMTQwNi8xMjE2MTQ0Nzc4MDczNjYucG5n.png)
可以看到子類的實例只有walk方法,而Parent1的say方法被覆蓋了。
總結:javascript是可以利用call方法和prototype屬性來實現多繼承的。繼承方法與單繼承相似,只是將需要繼承的多個父類依次實現,另外對於屬性或共有方法重命的時候,以最后繼承的屬性和方法為主。因為會覆蓋前面的繼承。