2012-05-18 91 views
4

鑑於A類和B類,其中B類從A類繼承...訪問子方法

// Define class A 
dojo.declare("mynamespace.A",null,{ 
    myMethodA: function() { this.myMethodB() } 
}); 

// Define class B 
dojo.declare("mynamespace.B",mynamespace.A,{ 
    myMethodB: function() {} 
}); 

是否合法調用this.myMethodB()的範圍A類(父類)? 我在一款軟件中看到過這個,我不明白。我知道在Java中,除非將類型A轉換爲B,否則這是不可能的。但dojo有什麼不同?

+0

從技術上講,這是可能的。該語言不禁止這一點。 – akonsu

+0

有計劃使用AMD模式來隱藏全局聲明,即我們需要通過本地變量而不是全局(可調整)範圍來引入依賴和引用。檢查是否可以通過dojo.has(「config-publishRequireResults」)訪問所需的模塊。它仍然,目前默認行爲 – mschr

回答

1

你這個問題的流行語是this.inherited(參數); 你的問題是調用一個不在當前繼承範圍內的方法 - 並且會被一個真正的面向對象的程序員稱爲invalid ..但是,由於加載器聲明瞭全局範圍內的所有內容,所以可能(仍)。您可以通過mynamespace.X訪問任何模塊,然後添加prototype.theMethod。

一旦你繼承了mynamespace.B,那麼A和B的所有功能都是'this'的作用域。這簡直就像是一個合併的散列,例如for all methods and variables in A do set instance B[key] = property A[key]

但是,如果你會遇到一個覆蓋,其中屬性爲'class'A和B兩個原型 - 在declare/construct鏈中有一個機制允許調用'super'(或父類,遵循你的符號)。

對於特殊的屬性構造函數,它總是如此,以至於繼承bubbles [period]。

對於那些宣稱只有一次的任何方法,你可以不尊重自己的稱呼它,如果它不是繼承的方法 - 然後將通過「這個」

對於具有覆蓋任何方法訪問,函數'this.inherited(arguments);'會向上發送給你,給被調用者的當前父類一個勾號。看看擴展小提琴here

var AClass = dojo.declare("mynamespace.A", null, { 
    constructor: function(args) { 
     this.overriddenMethod(); 
    }, 
    overriddenMethod: function() { 

    } 
}); 
var BClass = dojo.declare("mynamespace.B", [AClass], { 

    constructor: function() { }, 

    overriddenMethod: function() { 
     // call super before anything else is processed in this method 
     // by placing following call you can control function callflow 
     this.inherited(arguments); 
    } 
}); 

// will call A.constructor, then A.overriddenMethod 
new AClass(); 

// will call B.constructor, A.constructor, B.overriddenMethod and then 
// A.overriddenMethod via the call to super 
// in B.overriddenMethod which A.constructor 
// calls (note that A.constructor callflow 'aims' B.override not A.override) 
new BClass(); 
+0

順便說一句,關於靜態用戶空間,我傾向於使用這種形式:'var AClass = declare(。,。,{constructor:...}); AClass.ENUMA = 0; ...' – mschr

0

您可以使用原型對象調用任何方法。

myMethodA: function() { mynamespace.B.prototype.myMethodB(); } 

這裏是一個工作示例:

http://jsfiddle.net/cswing/7cBJm/

1

沒有在JavaScript中沒有靜態編譯,因此,作爲@akonsu還沒有提到的,在技術上是可行的,但它不是一個模式遵循:

var a = new mynamespace.A(); 
a.myMethodA(); // ilegal: Uncaught TypeError: Object [object Object] has no method 'methodB' 

var b = new mynamespace.B(); 
b.myMethodA() // legal 

您也可以在JavaScript中的給定範圍內執行方法/功能,即給出對象的方法:

a.myMethodA.call(b); // legal as `this` inside `myMethodA` will be referencing to object `b` 

實際上,我認爲mynamespace.A可以模擬抽象類與抽象方法myMethodB爲您從Java知道這一點。當子類別爲mynamespace.A時,子類應執行myMethodB。但做這種方式是非常容易出錯,我會做一個更強大的方式:

// Define class A 
dojo.declare("mynamespaca.A", null, { 

    myMethodA: function() { 
     this.myMethodB(); 
    }, 

    myMethodB: function() { 
     // abstract method 
     console.warn("Abstract method [myMethodB] was not implemented."); 
     // or: throw new Error("Abstract method [myMethodB] was not implemented."); 
    } 

}); 


// Define class B 
dojo.declare("mynamespace.B", mynamespace.A, { 

    myMethodB: function() { 
     // implement abstract method here 
    } 

});