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(){
……
}
}
});
無論在什麼語言中,類是重中之重,對類的學習不容忽視,目前僅算得上瞭解,博主會繼續努力。