javascript繼承(六)—實現多繼承

在上一篇javascript繼承—prototype最優兩種繼承(空函數和循環拷貝)(3) ,介紹了js較完美繼承的兩種實現方案,那麼下面來探討一下js裏是否有多繼承,如何實現多繼承。在這裏能夠看看java是如何處理多繼承的問題,java裏是沒有多繼承的,即一個子類不能同時繼承多個父類,但能夠實現多個接口,這也間接的實現了多繼承。主要是由於多繼承涉及到成員變量重名的問題,對於java這種強類型語言,是很很差操做的。因此java讓接口成的成員變量只能定義爲常量。這也解決了實現多個接口的問題。javascript

對於js來講,如何實現一個子類繼承多個父類呢?怎樣讓父類的特權屬性和共有方法實現比較完美的繼承呢?參考上一篇中的兩種繼承方式。會發現多繼承是不能用空函數來實現的,下面具體說明如何操做。html

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, 更多...}
 
 
age_thumb[1]

console.log(c1.constructor);//Child(name,age,weight)

能夠看到子類Child的實例c1打出的結果繼承了父類的全部屬性和方法。固然這裏存在一個問題,若是父類Parent1和Parent2都有name這個屬性的時候,會之後繼承的爲主。即這裏c1的name屬性爲170,覆蓋了Parent1的屬性180。java

能夠理解javascript的多繼承其實就是前面介紹的js循環拷貝繼承的屢次使用。下面來說講爲何空函數繼承的方法是不行的。一樣舉例說明:函數

2、用空函數實現多繼承(此方法不行)this

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]
 

能夠看到子類的實例只有walk方法,而Parent1的say方法被覆蓋了。spa

總結:javascript是能夠利用call方法和prototype屬性來實現多繼承的。繼承方法與單繼承類似,只是將須要繼承的多個父類依次實現,另外對於屬性或共有方法重命的時候,以最後繼承的屬性和方法爲主。由於會覆蓋前面的繼承。prototype

相關文章
相關標籤/搜索