在面向对象的编程方法中,对象继承是必不可少的,那么怎么在javascript中实现继承机制呢。由于javascript并不是一个严格的面向对象的语言,因此在对象继承上也显的不一样。我们也来创建一个基类Polygon,代表一个多边形,一个多边形有个共同的属性就是边数(sides)和一个共同的方法计算面积(getAreas)。这样我们的这具Polygon类看起来就像下面这样定义:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
因为基类并不能确定面积,因此在这里我们返回为0。
接着我们就创建一个子类Triangle,一个三角形,显然这个三角形是要从多边形继承的,因此我们要让这个Triangle类继承Polygon类,并且要覆盖Polygon类的getAreas方法来返回三角形的面积。我们来看下在javascript中的实现:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
参考上面的实现,我们再定义一个矩形:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/34031c708bfe702fe82d01ff5c6593aa.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/587e34b10dcf5efbc0859b53470a2db3.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/4fd96b3cf02f4c7b5c8964ac8167f7af.gif)
好了,上面我们定义了一个基类和两个子数,下面我们来测试一个这两个子类是否能正常工作:
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/f0cd6c7f9e7ae96feae062cb48f670f0.gif)
2、类的定义采用动态原型方式-继承无法利用动态原型方式实现
继承无法利用动态原型方式实现,原因在于prototype的特性,问题主要是由下面代码的位置因此的:Triangle.prototype=new Polygon(); 因为在代码运行前,对象已被实例化,并与原始的prototype对象联系在了一起。虽然用极晚绑定可使对原型对象的修改正确地表现出来,但替换 prototype对象却不会对该对象产生任何影响。只有未来的实例才会反映出这种改变,所以上面的例子会出现错误。代码进行下面的修改以后,就可以正常运行了。
3、其他的继承方式--zInherit
(1)利用inheritfrom重写Polygon类
(2)动态原型支持
动态原型支持:原型链方式不能真正符合动态原型的主旨,即把类的所有代码放置在它的构造函数中。这种方法实现的原因是,使用inheritForm()方法时,并未重写prototype对象,只是为其加入方法而已。使用这种方法,即可避开原型链的限制,实现动态原型本意。
(3)多重继承支持
多重继承支持:zInherit库最有用的特性之一是支持多重继承,原型链不支持多重继承。同样利用inheritForm()方法实现。要继承属性和方法,inheritForm()方法必须与对象冒充一起使用,注意这里使用的是apply()方法。一般来说,按照继承属性的顺序继承方法比较好。
- function Polygon(iSides){
- this.sides=iSides;
- if(typeof Polygon._initialized_=="undefined"){
- Polygon.prototype.getArea=function(){
- return 0;
- }
- }
- Polygon._initialized_=true;
- }
- function Triangle(iLength,iWidth){
- Polygon.call(this,3);
- this.length=iLength;
- this.width=iWidth;
- if(typeof Triangle._initialized_=="undefined"){
- Triangle.prototype=new Polygon();
- Triangle.prototype.getArea=function(){
- return (this.length)*(this.width);
- }
- }
- Triangle._initialized_=true;
- }
- var oTriangle=new Triangle(4,8);
- //控制台输出错误消息"oTriangle.getArea is not a function"
- alert(oTriangle.getArea());
继承无法利用动态原型方式实现,原因在于prototype的特性,问题主要是由下面代码的位置因此的:Triangle.prototype=new Polygon(); 因为在代码运行前,对象已被实例化,并与原始的prototype对象联系在了一起。虽然用极晚绑定可使对原型对象的修改正确地表现出来,但替换 prototype对象却不会对该对象产生任何影响。只有未来的实例才会反映出这种改变,所以上面的例子会出现错误。代码进行下面的修改以后,就可以正常运行了。
- function Polygon(iSides){
- this.sides=iSides;
- if(typeof Polygon._initialized_=="undefined"){
- Polygon.prototype.getArea=function(){
- return 0;
- }
- }
- Polygon._initialized_=true;
- }
- function Triangle(iLength,iWidth){
- Polygon.call(this,3);
- this.length=iLength;
- this.width=iWidth;
- if(typeof Triangle._initialized_=="undefined"){
- Triangle.prototype.getArea=function(){
- return 0.5*(this.length)*(this.width);
- }
- }
- Triangle._initialized_=true;
- }
- Triangle.prototype=new Polygon();
- var oTriangle=new Triangle(4,8);
- alert(oTriangle.getArea());//16
3、其他的继承方式--zInherit
(1)利用inheritfrom重写Polygon类
- function Polygon(iSides){
- this.sides=iSides;
- }
- Polygon.prototype.getArea=function(){
- return 0;
- }
- function Triangle(iBase,iHeight){
- Polygon.call(this,3);
- this.base=iBase;
- this.height=iHeight;
- }
- Triangle.prototype.inheritFrom(Polygon);
- Triangle.prototype.getArea=function(){
- return 0.5*(this.base)*(this.height);
- }
- function Rectangle(iLength,iWidth){
- Polygon.call(this,4);
- this.length=iLength;
- this.width=iWidth;
- }
- Rectangle.prototype.inheritFrom(Polygon);
- Rectangle.prototype.getArea=function(){
- return (this.length)*(this.width);
- }
- var oTri=new Triangle(4,8);//16
- alert(oTri.getArea());
- var oRec=new Rectangle(4,8);//32
- alert(oRec.getArea());
- alert(oTri.instanceOf(Polygon));//true
- alert(oTri.instanceOf(Triangle));//true
- alert(oRec.instanceOf(Polygon));//true
- alert(oRec.instanceOf(Rectangle));//true
(2)动态原型支持
动态原型支持:原型链方式不能真正符合动态原型的主旨,即把类的所有代码放置在它的构造函数中。这种方法实现的原因是,使用inheritForm()方法时,并未重写prototype对象,只是为其加入方法而已。使用这种方法,即可避开原型链的限制,实现动态原型本意。
- //dinamic prototype support
- function Polygon(iSides){
- this.sides=iSides;
- if(typeof Polygon._initialized_=="undefined"){
- Polygon.prototype.getArea=function(){
- return 0;
- }
- }
- return Polygon._initialized_=true;
- }
- function Triangle(iBase,iHeight){
- Polygon.call(this,3);
- this.base=iBase;
- this.height=iHeight;
- if(typeof Triangle._initialized_=="undefined"){
- Triangle.prototype.inheritFrom(Polygon);
- Triangle.prototype.getArea=function(){
- return 0.5*(this.base)*(this.height);
- }
- }
- Triangle._initialized_=true;
- }
- function Rectangle(iLength,iWidth){
- Polygon.call(this,4);
- this.length=iLength;
- this.width=iWidth;
- if(typeof Rectangle._initialized_=="undefined"){
- Rectangle.prototype.inheritFrom(Polygon);
- Rectangle.prototype.getArea=function(){
- return (this.length)*(this.width);
- }
- }
- Rectangle._initialized_=true;
- }
- var tri=new Triangle(4,8);
- alert(tri.getArea());//16
- alert(tri.instanceOf(Polygon));//true
- alert(tri.instanceOf(Triangle));//true
- var rec=new Rectangle(4,8);
- alert(rec.getArea());//32
- alert(rec.instanceOf(Polygon));//true
- alert(rec.instanceOf(Rectangle));//true
(3)多重继承支持
多重继承支持:zInherit库最有用的特性之一是支持多重继承,原型链不支持多重继承。同样利用inheritForm()方法实现。要继承属性和方法,inheritForm()方法必须与对象冒充一起使用,注意这里使用的是apply()方法。一般来说,按照继承属性的顺序继承方法比较好。
- //multiple inheritance support
- function ClassA(){
- this.messageA="the message of Class A";
- if(typeof ClassA._initialized_=="undefined"){
- ClassA.prototype.showMessageA=function(){
- alert(this.messageA);
- };
- ClassA._initialized_=true;
- }
- }
- function ClassB(){
- this.messageB="the message of Class B";
- if(typeof ClassB._initialized_=="undefined"){
- ClassB.prototype.showMessageB=function(){
- alert(this.messageB);
- };
- ClassB._initialized_=true;
- }
- }
- function ClassC(){
- ClassA.apply(this);
- ClassB.apply(this);
- this.messageC="the message of Class C";
- if(typeof ClassC._initialized_=="undefined"){
- ClassC.prototype.inheritFrom(ClassA);
- ClassC.prototype.inheritFrom(ClassB);
- ClassC.prototype.showMessageC=function(){
- alert(this.messageC);
- };
- ClassC._initialized_=true;
- }
- }
- var cClass=new ClassC();
- cClass.showMessageA();//the message of Class A
- cClass.showMessageB();//the message of Class B
- cClass.showMessageC();//the message of Class C