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


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

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]
 

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM