从Java的角度理解Ext的extend

发表于:2011-12-29 09:33

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Adley    来源:51Testing软件测试网采编

  我们说在java中必须写两个类,每个类都写自己的字段 ,构造函数,方法等,在我们实现的extend函数中也确实把子类,父类都传递了进来,但是我们多了一个参数,那就是子类的方法集合即sbm,第一个参数sb本身也是函数,那是不是可以将这个函数也放进sbm传进来呢?这样extend就变为两个参数,即extend(sp,sbm),现在extend返回一个函数,返回的这个函数就是sp的子类,这是完全可行的,我们叫做extend2吧。

  1. var extend2 = function(sp, sbm) {  
  2.     var sb = sbm.constructor;  
  3.     //如果说没有显式的构造函数,那么子类就是直接调用超类构造函数  
  4.     if (sb == Object) {  
  5.         sb = function() {  
  6.             sp.apply(this, arguments);  
  7.         };  
  8.     }  
  9.     extend(sb, sp, sbm);  
  10.     return sb;  
  11. }

  我们说要把子类的构造函数放到sbm上,放上去的key叫做constructor,就表示构造器,js中每一个对象都一个constructor属性,它指向构造了这个对象构造函数。sbm本来是个Object对象,它的constructor就指向Object,这个constructor是在sbm关联的那个原型上的,现在我们在sbm上设置某个子类的构造函数,这个时候表示sbm有个自己的constructor。

  现在我们在extend2中要做的事情就是提取出构造函数,然后还原为三个参数去调用之前的extend,在java中我们的子类是可以不用构造器的,只要父类也有默认的构造器,那么在这里一样,sbm可能不包含constructor,那么我们需要做一个函数,它调用父类的构造函数,在java中这种情况过程是自动的。所以当sbm.constructor为Object的时候表示sbm没有指定构造函数,这个时候将

  1. sb = function() {  
  2.             sp.apply(this, arguments);  
  3.         };

  即调用父类构造函数。这样将sb,sp,sbm传递给extend就可以了。

  这个时候我们新的继承语法如下:

  1. var NewSpace = extend2(Plane, {  
  2.             constructor : function(x, y, z) {  
  3.                 Plane.call(this, x, y);  
  4.                 this.z = z;  
  5.             },  
  6.             XYZ : function() {  
  7.                 alert(this.x * this.y * this.z);  
  8.             }  
  9.         });  
  10.  
  11. var newObject = new NewSpace(345);  
  12. newObject.XY();  
  13. newObject.XYZ();

  和prototype.js和mootolls的实现比较,大同小异

  1. // properties are directly passed to `create` method  
  2. var Person = Class.create({  
  3.   initialize: function(name) {  
  4.     this.name = name;  
  5.   },  
  6.   say: function(message) {  
  7.     return this.name + ': ' + message;  
  8.   }  
  9. });

  1. var Animal = new Class({  
  2.                 initialize: function(age) {  
  3.                     this.age = age;  
  4.                 },  
  5.                 say : function() {  
  6.                     alert(this.age);  
  7.                 }  
  8.             });  
  9.  
  10.     var Cat = new Class({  
  11.                 Extends: Animal,  
  12.                 initialize: function(name, age) {  
  13.                     this.parent(age); // calls initalize method of Animal class  
  14.                     this.name = name;  
  15.                 }  
  16.             });

  到了这里其实已经差不多了,但是细心的读者会发现,我们在extend中会把sbm的所有属性拷贝到子类的原型上,这里岂不是就要把constructor也拷贝到原型上?如果sbm包含了这个constructor其实就无所谓,因为子类的原型的constructor本来就是需要指向这个构造函数的,但是sbm上没有constructor那岂不是要把Object拷贝到子类原型上,答案是不会的,我们在拷贝的时候用的for in循环是迭代不出默认的那个constructor的。

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号