Javascript对象继承

在面向对象的编程方法中,对象继承是必不可少的,那么怎么在javascript中实现继承机制呢。由于javascript并不是一个严格的面向对象的语言,因此在对象继承上也显的不一样。我们也来创建一个基类Polygon,代表一个多边形,一个多边形有个共同的属性就是边数(sides)和一个共同的方法计算面积(getAreas)。这样我们的这具Polygon类看起来就像下面这样定义:

function  Polygon(iSides)
{
    
this.sides = iSides;
}


Polygon.prototype.getAreas 
=   function ()
{
    
return 0;
}

因为基类并不能确定面积,因此在这里我们返回为0。
接着我们就创建一个子类Triangle,一个三角形,显然这个三角形是要从多边形继承的,因此我们要让这个Triangle类继承Polygon类,并且要覆盖Polygon类的getAreas方法来返回三角形的面积。我们来看下在javascript中的实现:

function  Triangle(iBase, iHeight)
{
    Polygon.call(
this,3);      //在这里我们用Polygon.call()来调用Polygon的构造函数,并将3作为参数,表示这是一个三角形,因为边是确定的,所以在子类的构造函数中就不需要指定边了
    this.base = iBase;         //三角形的底
    this.height = iHeight;     //三角形的高
}


Triangle.prototype 
=   new  Polygon();
Triangle.prototype.getAreas 
=   function ()
{
    
return 0.5 * this.base *this.height;  //覆盖基类的getAreas方法,返回三角形的面积
}

参考上面的实现,我们再定义一个矩形:

function  Rectangle(iWidth, iHeight)
{
    Polygon.call(
this,4);//用对象冒充继承构造函数的属性   
    
this.width = iWidth;
    
this.height = iHeight;
}


Rectangle.prototype 
=   new  Polygon();//用原型链继承prototype对象的方法
Rectangle.prototype.getAreas 
=   function ()
{
    
return this.width * this.height;
}


好了,上面我们定义了一个基类和两个子数,下面我们来测试一个这两个子类是否能正常工作:

var  t  =   new  Triangle( 3 , 6 );
var  r  =   new  Rectangle( 4 , 5 );

alert(t.getAreas());    
// 输出9说明正确
alert(r.getAreas());     // 输出20说明正确
2、类的定义采用动态原型方式-继承无法利用动态原型方式实现
Javascript代码 复制代码
  1. function Polygon(iSides){   
  2.     this.sides=iSides;   
  3.     if(typeof Polygon._initialized_=="undefined"){   
  4.         Polygon.prototype.getArea=function(){   
  5.             return 0;   
  6.         }   
  7.      }   
  8.      Polygon._initialized_=true;   
  9. }   
  10. function Triangle(iLength,iWidth){   
  11.     Polygon.call(this,3);   
  12.     this.length=iLength;   
  13.     this.width=iWidth;   
  14.     if(typeof Triangle._initialized_=="undefined"){   
  15.     Triangle.prototype=new Polygon();   
  16.     Triangle.prototype.getArea=function(){   
  17.         return (this.length)*(this.width);   
  18.         }   
  19.     }   
  20.     Triangle._initialized_=true;   
  21. }   
  22. var oTriangle=new Triangle(4,8);   
  23. //控制台输出错误消息"oTriangle.getArea is not a function"   
  24. alert(oTriangle.getArea());  

继承无法利用动态原型方式实现,原因在于prototype的特性,问题主要是由下面代码的位置因此的:Triangle.prototype=new Polygon(); 因为在代码运行前,对象已被实例化,并与原始的prototype对象联系在了一起。虽然用极晚绑定可使对原型对象的修改正确地表现出来,但替换 prototype对象却不会对该对象产生任何影响。只有未来的实例才会反映出这种改变,所以上面的例子会出现错误。代码进行下面的修改以后,就可以正常运行了。
Javascript代码 复制代码
  1. function Polygon(iSides){   
  2.     this.sides=iSides;   
  3.     if(typeof Polygon._initialized_=="undefined"){   
  4.         Polygon.prototype.getArea=function(){   
  5.             return 0;   
  6.         }   
  7.      }   
  8.      Polygon._initialized_=true;   
  9. }   
  10. function Triangle(iLength,iWidth){   
  11.     Polygon.call(this,3);   
  12.     this.length=iLength;   
  13.     this.width=iWidth;   
  14.     if(typeof Triangle._initialized_=="undefined"){   
  15.     Triangle.prototype.getArea=function(){   
  16.         return 0.5*(this.length)*(this.width);   
  17.         }   
  18.     }   
  19.     Triangle._initialized_=true;   
  20. }   
  21. Triangle.prototype=new Polygon();   
  22. var oTriangle=new Triangle(4,8);   
  23. alert(oTriangle.getArea());//16  

3、其他的继承方式--zInherit
(1)利用inheritfrom重写Polygon类
Jjavascript代码 复制代码
  1. function Polygon(iSides){   
  2.     this.sides=iSides;   
  3. }   
  4. Polygon.prototype.getArea=function(){   
  5.     return 0;   
  6. }   
  7. function Triangle(iBase,iHeight){   
  8.     Polygon.call(this,3);   
  9.     this.base=iBase;   
  10.     this.height=iHeight;   
  11. }   
  12. Triangle.prototype.inheritFrom(Polygon);   
  13. Triangle.prototype.getArea=function(){   
  14.     return 0.5*(this.base)*(this.height);   
  15. }   
  16. function Rectangle(iLength,iWidth){   
  17.     Polygon.call(this,4);   
  18.     this.length=iLength;   
  19.     this.width=iWidth;   
  20. }   
  21. Rectangle.prototype.inheritFrom(Polygon);   
  22. Rectangle.prototype.getArea=function(){   
  23.     return (this.length)*(this.width);   
  24. }   
  25. var oTri=new Triangle(4,8);//16  
  26. alert(oTri.getArea());   
  27. var oRec=new Rectangle(4,8);//32  
  28. alert(oRec.getArea());   
  29. alert(oTri.instanceOf(Polygon));//true   
  30. alert(oTri.instanceOf(Triangle));//true   
  31. alert(oRec.instanceOf(Polygon));//true   
  32. alert(oRec.instanceOf(Rectangle));//true  

(2)动态原型支持
动态原型支持:原型链方式不能真正符合动态原型的主旨,即把类的所有代码放置在它的构造函数中。这种方法实现的原因是,使用inheritForm()方法时,并未重写prototype对象,只是为其加入方法而已。使用这种方法,即可避开原型链的限制,实现动态原型本意。
Javascript代码 复制代码
  1. //dinamic prototype support   
  2. function Polygon(iSides){   
  3.     this.sides=iSides;   
  4.     if(typeof Polygon._initialized_=="undefined"){   
  5.         Polygon.prototype.getArea=function(){   
  6.             return 0;   
  7.         }   
  8.     }   
  9.     return Polygon._initialized_=true;   
  10. }   
  11. function Triangle(iBase,iHeight){   
  12.     Polygon.call(this,3);   
  13.     this.base=iBase;   
  14.     this.height=iHeight;   
  15.     if(typeof Triangle._initialized_=="undefined"){   
  16.         Triangle.prototype.inheritFrom(Polygon);   
  17.         Triangle.prototype.getArea=function(){   
  18.             return 0.5*(this.base)*(this.height);   
  19.         }   
  20.     }   
  21.     Triangle._initialized_=true;   
  22. }   
  23. function Rectangle(iLength,iWidth){   
  24.     Polygon.call(this,4);   
  25.     this.length=iLength;   
  26.     this.width=iWidth;   
  27.     if(typeof Rectangle._initialized_=="undefined"){   
  28.         Rectangle.prototype.inheritFrom(Polygon);   
  29.         Rectangle.prototype.getArea=function(){   
  30.             return (this.length)*(this.width);   
  31.         }   
  32.     }   
  33.     Rectangle._initialized_=true;   
  34. }   
  35. var tri=new Triangle(4,8);   
  36. alert(tri.getArea());//16   
  37. alert(tri.instanceOf(Polygon));//true   
  38. alert(tri.instanceOf(Triangle));//true   
  39. var rec=new Rectangle(4,8);   
  40. alert(rec.getArea());//32   
  41. alert(rec.instanceOf(Polygon));//true   
  42. alert(rec.instanceOf(Rectangle));//true  

(3)多重继承支持
多重继承支持:zInherit库最有用的特性之一是支持多重继承,原型链不支持多重继承。同样利用inheritForm()方法实现。要继承属性和方法,inheritForm()方法必须与对象冒充一起使用,注意这里使用的是apply()方法。一般来说,按照继承属性的顺序继承方法比较好。
Javascript代码 复制代码
  1. //multiple inheritance support   
  2. function ClassA(){   
  3.     this.messageA="the message of Class A";   
  4.     if(typeof ClassA._initialized_=="undefined"){   
  5.         ClassA.prototype.showMessageA=function(){   
  6.             alert(this.messageA);   
  7.         };   
  8.     ClassA._initialized_=true;   
  9.     }   
  10. }   
  11. function ClassB(){   
  12.     this.messageB="the message of Class B";   
  13.     if(typeof ClassB._initialized_=="undefined"){   
  14.         ClassB.prototype.showMessageB=function(){   
  15.             alert(this.messageB);   
  16.         };   
  17.     ClassB._initialized_=true;   
  18.     }   
  19. }   
  20. function ClassC(){   
  21.     ClassA.apply(this);   
  22.     ClassB.apply(this);   
  23.     this.messageC="the message of Class C";   
  24.     if(typeof ClassC._initialized_=="undefined"){   
  25.         ClassC.prototype.inheritFrom(ClassA);   
  26.         ClassC.prototype.inheritFrom(ClassB);   
  27.         ClassC.prototype.showMessageC=function(){   
  28.             alert(this.messageC);   
  29.         };   
  30.     ClassC._initialized_=true;   
  31.     }   
  32. }      
  33. var cClass=new ClassC();   
  34. cClass.showMessageA();//the message of Class A   
  35. cClass.showMessageB();//the message of Class B   
  36. cClass.showMessageC();//the message of Class C  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值