从Java的角度理解Ext的extend (三)

2014-11-24 03:19:37 · 作者: · 浏览: 3
}; //子类这个构造函数要么是外界传入的名字为constructor,要么就是直接调用超类构造函数的一个函数

//传入的constructor除了构造自己还要调用超类的构造函数

}

/**

* 继承的两种参数

* 1,自己写一个构造函数,初始化一些字段,然后调用超类构造函数,再写一个json对象,里面是要覆盖超类的方法或者追加的方法

* 然后这样调用extend(sub,sup,{over1:f,over2:f,addf:f}),就像java的语法

* SubClass extend SuperClass {

* SubClass(){

* super();

* }

* }

*

* 2,第一种可以理解为模拟java,但是因为构造函数也是数据,所以完全可以把构造函数也放进那个jdon对象,只不过约定好一个名字

* 比如constructor,然后这样调用

* extend(sup,{constructor:f,over1:f,over2:f,addf:f})

*/

var F = function() {

},

sbp,

spp = sp.prototype;

F.prototype = spp;

sbp = sb.prototype = new F();

//以上用干净函数嫁接得到子类原型

sbp.constructor = sb; //然后指定一个constructor指回子类,这样就大工告成

sb.superclass = spp; //在子类上指定一个静态字段指向超类原型,这样在子类构造函数中可访问超类构造函数sub.superclass.constructor.call(this, config)

/**

* 这段代码是防御性的,在自己实现继承的时候,可能会出现原型上的构造函数指向问题,所以如果发现某个超类

* 的构造函数是object,要么这个超类却是Object,要么出现了失误,所以这里再一次重设置一下,以防万一,这个代码我们在分析Ext的Observable的时候会提到的它的作用

*/

if (spp.constructor == oc) {

spp.constructor = sp;

}

//子类上方一个静态的重写方法,注意js没有重载,可以用来重写子类原型上的函数

sb.override = function(o) {

Ext.override(sb, o);

};

//用一个闭包在子类原型上引用一个超类原型,引用的是一个函数

sbp.superclass = sbp.supr = (function() {

return spp;

});

//子类原型上放置一个重写函数,可以用来覆盖具体实例对象

sbp.override = io;

//在子类原型上重写或添加函数

Ext.override(sb, overrides);

//子类上直接放一个静态继承方法,貌似实现多继承

sb.extend = function(o) {

return Ext.extend(sb, o);

};

return sb;

};

}();

现在使用Ext的extend来实现我们之前的继承代码就如下

var Plane = function(o) {

this.x = o.x;

this.y = o.y;

};

Plane.prototype.XY = function() {

alert(this.x * this.y);

};

var Space = Ext.extend(Plane, {

constructor : function(o) {

Space.superclass.constructor.call(this, o);

this.z = o.z;

},

XYZ : function() {

alert(this.x * this.y * this.z);

}

});

var space = new Space({ x:2,y:3,z:4});

space.XY();

space.XYZ();

现在我们来分析一下Ext中的继承重头戏Observable,它位于Ext.util这个包下,它的意思即是观察者,使用观察者模式,EDA模式,UI组件就利用这种基于观察和事件的机制进行通信和渲染。

所有的UI组件都继承这个类,我们看看它的构造函数

EXTUTIL.Observable = function(){

var me = this, e = me.events;

if(me.listeners){

me.on(me.listeners);

delete me.listeners;

}

me.events = e || {};

};

这个构造函数不需要参数,在java中,这种父类的构造可以自动的调用默认构造函数,但是这里要注意,if(me.listeners)依赖了子类的构造行为,这在面向对象原则中似乎是一个禁忌,但是如果一个继承体现完全由一个团队维护,他们同时制定继承规则和继承规范,这也无可厚非,这里的listeners可以在子类中不提供,可以让构造出来的对象自己调用on方法来添加监听器,同理这里的events,如果子类没构造会被赋值为一个空对象。那么这个Observable构造器做了两个事,一个是看子类是否在对象上放了监听器,如果放了,就让对象指向on方法进行事件和监听的绑定,二是看子类是否在对象上放置了events,如果没有就把对象的events属性设置为一个空对象。也就是说子类是完全可以不做任何事的,子类只负责自己的数据构造和行为覆盖或追加。

Observable原型上放置的方法都是子类继承的方法,子类的对象就可以在运行时调用这些方法,如下:

\

原型上放置了一个静态变量和一些方法,这些方法都是和事件以及监听有关,注意

Observable

的原型是一个新的对象直接量,它的

co