JavaScript繼承方式(1)

作者: snandy  來源: 博客園  發布時間: 2011-03-10 16:21  閱讀: 2276 次  推薦: 1   原文鏈接   [收藏]  

  前段時間溫故了下JS OO之寫類方式,從這篇開始我們看看JS OO之繼承方式。

  面向對象的語言多數都支持繼承,繼承最重要的優點就是代碼復用,從而構建大型軟件系統。如果一個類能夠重用另一個類的屬性和或方法,就稱之為繼承。從這個角度來看看JS的繼承方式。JS中繼承方式與寫類方式息息相關。不同的寫類方式造成不同的繼承方式。各種流行JS庫繼承方式也各不相同。從最簡單的復用開始。

  1、構造函數方式寫類,通過方法調用復制父類屬性/字段到子類 實現繼承

  這里父類,子類都采用構造函數方式寫,不用原型。子類調用父類函數來復制父類的屬性。

 
/**
* 父類Polygon:多邊形
* @param {Object} sides

*/
function Polygon(sides) {
this.sides = sides;
this.setSides = function(s) {this.sides=s;}
}


/**
* 子類Triangle:三角形

*/
function Triangle() {
this.tempfun = Polygon;//父類引用賦值給子類的一個屬性tempfun
this.tempfun(3);//調用
delete this.tempfun;//刪除該屬性
this.getArea = function(){};
}


//new個對象
var tri = new Triangle();
console.log(tri.sides);
//繼承的屬性
console.log(tri.setSides);//繼承的方法
console.log(tri.getArea);//自有的方法

//缺點是對于Triangle的實例對象用instanceof為父類Polygon時是false
console.log(tri instanceof Triangle);//true
console.log(tri instanceof Polygon);//false

  因為 JavaScript中具名函數的多種調用方式 ,子類還可以有以下的多種實現方式。只是在子類中調用父類方法不同而已。

 
function Triangle() {
Polygon.call(
this,3); //call方式調用父類
this.getArea = function(){};
}

function Triangle() {
Polygon.apply(
this,[3]); //apply方式調用父類
this.getArea = function(){};
}

function Triangle() {
var temp = new Polygon(3); //new方式調用父類
for(atr in temp) { //全部復制給子類
this[atr] = temp[atr];
}

this.getArea = function(){};
}

  這種方式的缺點是子類的實例對象用instanceof檢查父類時總是false。這與java中繼承"is a "的關系是違背的。

  2、原型方式寫類,原型方式繼承

  core JS自身的對象系統就是采用原型方式(prototype based)繼承的。或者說core JS沒有采用常見的類繼承(class based)系統,而是使用原型繼承來實現自己的對象系統。工作中我們也可以用原型方式來實現繼承,代碼復用以構建自己的功能模塊。

 
/**
* 父類Polygon:多邊形
*

*/
function Polygon() {}
Polygon.prototype.sides
= 0;
Polygon.prototype.setSides
= function(s) {this.sides=s;}

/**
* 子類Triangle:三角形

*/
function Triangle() {}
Triangle.prototype
= new Polygon(); //這是原型繼承關鍵的一句
Triangle.prototype.getArea = function(){}

//new個對象
var tri = new Triangle();
console.log(tri.sides);
//繼承的屬性
console.log(tri.setSides);//繼承的方法
console.log(tri.getArea);//自有方法

//instanceof測試
console.log(tri instanceof Triangle);//true,表明該對象是三角形
console.log(tri instanceof Polygon);//true,表明三角形也是多邊形

  雖然從輸出可以看出子類繼承了父類Polygon的屬性sides和方法setSides,但sides是0,怎么會是三角形呢。還得調用下tri.setSides(3)使之成為三角形。這樣似乎很不方便。不能傳參數,即是原型方式的缺點。優點是正確的維護了"is a"的關系。

  3、組合構造函數/原型方式寫類,采用前面種方式繼承

  這種方式父類,子類的屬性都掛在構造函數里,方法都掛在原型上。

 
/**
* 父類Polygon:多邊形

*/
function Polygon(sides) {
this.sides = sides;
}
Polygon.prototype.setSides
= function(s) {this.sides=s;}

/**
* Triangle 三角形
* @param {Object} base 底
* @param {Object} height 高

*/
function Triangle(base,height) {
Polygon.call(
this,3);//復制父類屬性給自己
this.base = base;
this.height = height;
}
Triangle.prototype
= new Polygon();//復制父類方法給自己

Triangle.prototype.getArea = function(){ //最后定義自己的方法
return this.base*this.height/2;
}

//new個對象
var tri = new Triangle(12,4);
console.log(tri.sides);
//繼承的屬性
console.log(tri.setSides);//繼承的方法
console.log(tri.base);//自有屬性
console.log(tri.height);//自有屬性
console.log(tri.getArea);//自有方法

//instanceof測試,表明正確的維護了"is a"的關系
console.log(tri instanceof Triangle);//true,表明該對象是三角形
console.log(tri instanceof Polygon);//true,表明三角形也是多邊形
1
0
 
標簽:JavaScript
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()