Dojo通过dojo.declare方法实现类的声明和继承。首先,来看一下最简单的情况——如何使用dojo.declare声明一个类。接着,讲述了类如何实现继承和多继承。分两种情况讲述了如何正确的调用父类的方法。最后,给出了声明静态成员的方法。
1. 类的声明
dojo.declare('my.classes.foo',null,{
protoId:'foo',
method:function(){
return "I am a foo";
}
}
);
上面的代码使用 dojo.declare声明了一个名为my.classes.foo的类,它具有一个成员变量protoId和一个成员方法method。声明了my.classes.foo类之后,可以使用new关键字创建该类的对象实例。
var obj=new my.classes.foo();
2. 类的继承
dojo.declare('my.classes.bar', my.classes.foo,{
protoId:'bar',
method:function(){
return "I am a bar";
},
barId:'barId'
}
);
my.classes.bar类继承自my.classes.foo,它覆盖了父类的成员变量protoId和成员方法method,同时声明了新的成员变量barId。
3. 类的多继承
dojo.declare('my.classes.bar', [my.classes.foo,my.classes.mixin],{
protoId: 'bar',
method: function(){
return "I am a bar";
},
barId: 'barId'
});
my.classes.bar类继承自my.classes.foo和my.classes.mixin类的属性和方法,但是在这里,两个父类并不是平等的关系,实际上,my.classes.bar只是my.classes.foo的子类,它复制了一份my.classes.mixin类所具有的属性和方法。通过这种方式,dojo.declare实现了“多继承”的效果。
4. 调用父类方法
前面定义的my.classes.bar类覆盖了父类my.classes.foo的method方法,如何在子类中调用父类的方法呢?Dojo声明类具有superclass属性。
第一种情况:在只有一层继承关系时
我们只需对my.classes.bar类中method方法的定义做一下修改,如下所示:
method: function(){
return "I am a bar and"+
this.constructor.superclass.method.apply(this,arguments);
}
返回结果: "I am a bar and I am a foo"。
第二种情况:在具有多重继承关系时
我们定义一个新类my.classes.zot,它是my.classes.bar的子类,现在继承关系是my.classes.zot-->my.classes.bar-->my.classes.foo。
错误的调用方法:
假设,新类my.classes.zot的method方法如下所示:
method: function(){
return "I am a zot and"+
this.constructor.superclass.method.apply(this,arguments);
}
在调用zot的method方法时,使得bar的method方法重复调用,导致堆栈溢出。
正确的调用方法:
Dojo创建的JavaScript类中包括一个inherited方法,通过它调用父类的方法。对bar和zot的method方法进行修改,即,添加 inherited方法后的代码如下:
dojo.declare('my.classes.bar', my.classes.foo, {
protoId: 'bar',
method: function(){
return "I am a bar" +
this.inherited('method', arguments);
},
barId: 'barId'
});
dojo.declare('my.classes.zot', my.classes.bar, {
protoId: 'zot',
method: function(){
return "I am a zot and " +
this.inherited('method', arguments);
},
});
5. 类的构造方法
类的构造方法使用initializer属性进行声明,例如:
dojo.declare('my.classes.foo', null, {
initializer:function(arg){
this.protoId='foo initialized';
},
protoId: 'foo',
method: function(){
return "I am a foo";
}
});
在子类中声明的构造函数会自动调用父类中的构造函数,例如:
dojo.declare('my.classes.bar', my.classes.foo, {
initializer: function(arg){
this.protoId = 'bar initialized';
},
protoId: 'bar',
method: function(){
return "I am a bar" +
this.inherited('method', arguments);
},
barId: 'barId'
});
声明:在创建 my.classes.bar类的对象实例时,首先调用父类my.classes.foo的构造函数,然后再调用子类的构造函数。
6. 声明静态成员
通过dojo.declare声明的成员都是类的实例成员,每一个对象的实例都是独立的。如果希望在类中声明一下静态成员在该类的所有对象实例中共享,可以使用如下方式:
dojo.declare('my.classes.foo', null, {
initializer: function(arg){
this.protoId = 'foo initialized';
},
protoId: 'foo',
method: function(){
return "I am a foo";
},
statics:{
staticInt:0,
staticString:"test",
StaticFunc:function(){
……
}
}
});
无论在什么语言中,类是重中之重,对类的学习不容忽视,目前仅算得上了解,博主会继续努力。