2012-05-10 22 views
2

祖先類確實有一個叫做「foo」的函數(爲了舉例)。如何在ActionScript對象的祖先類上調用靜態函數?

public static function callAncestorStaticMethod() : void 
{ 
    var ancestorClassName : String = getQualifiedSuperclassName(Descendant); 
    var ancestorClass : Class = Class(getDefinitionByName(ancestorClassName)); 

    ancestorClass.foo(); // <---- runtime error here: foo is not a function 
} 

檢查ancestorClass發現它是一個沒有可見屬性的對象(ancestorClass.prototype也不)。

那麼,當我在運行時只有名稱作爲字符串時,如何在類上調用靜態函數?

回答

4

我可以使用下面的代碼來調用父類的靜態函數:

var c:ChildClass = new ChildClass(); 
var s:String = getQualifiedSuperclassName(c); 
var cl:Class = getDefinitionByName(s) as Class; 

cl.foo.call(); 
//cl["foo"].call(); 

A類對象具有的所有靜態屬性和方法的該類,所以這應該是可靠的。 cl.foo返回一個Function對象,然後您可以.call()

+0

祕密的握手了。呼叫() –

1

您可以使用constructor屬性獲取實例自己的類的引用,但要訪問祖先類,必須使用describeTypegetDefinitionByName。這些功能強大,但昂貴的 - 所以一定要確保你不要濫用這一點:

function callStaticAncestorProperty(instance:Object, staticProperty:String):* { 
    var type:XML = describeType(instance); 
    var ret:* = instance.constructor[staticProperty]; 
    for each(var extend:XML in type.extendsClass) 
     ret = ret ? ret : getStaticPropertyOrUndefined(extend, staticProperty); 
    return ret; 
} 

function getStaticPropertyOrUndefined(extend:XML, staticProperty:String):* { 
    var clazz:Class = getDefinitionByName([email protected]().replace("::", ".")) as Class; 
    return clazz[staticProperty] ? clazz[staticProperty] : undefined; 
} 

這用來檢查類本身所具有的屬性,然後在每個超類型進行迭代。請注意,要返回的第一個值將被返回,即如果子類和超類都具有此屬性,則將返回子類的值。

編輯

我纔剛剛意識到你詢問的方法調用,而不是屬性。這工作幾乎相同的方式:

function callStaticAncestorMethod(instance:Object, staticMethod:String):void { 
    var type:XML = describeType(instance); 
    var method:Function = instance.constructor[staticMethod]; 
    for each(var extend:XML in type.extendsClass) 
     method = method ? method : getStaticMethodOrUndefined(extend, staticMethod); 
    if (method) method(); 
} 

function getStaticMethodOrUndefined(extend:XML, staticMethod:String):Function { 
    var clazz:Class = getDefinitionByName([email protected]().replace("::", ".")) as Class; 
    return clazz[staticMethod] ? clazz[staticMethod] : undefined; 
} 
0

或(基於山姆DeHaan答案的):

如果在超和後代都具有一個String id屬性...

(getDefinitionByName(getQualifiedSuperclassName(Descendant))as Class).foo(); 
trace((getDefinitionByName(getQualifiedSuperclassName(Descendant))as Class).id); 

其中:

// trace (Descendant.id); 
// if private : compile time Error. 
// 1178: Attempted access of inaccessible property id through a reference with static type Class. 
var d:Descendant; 
trace((getDefinitionByName("Descendant") as Class).id); 
// output undefined if private : the value if public. But don't throw compile time Error. 
(getDefinitionByName("Descendant") as Class).foo(); 
// Call static foo() from Descendant. // Throw a compile time Error if method is private 

// trace (Superclass.id); 
// if private : compile time Error. 
// 1178: Attempted access of inaccessible property id through a reference with static type Class. 
var s:Superclass; 
trace((getDefinitionByName("Superclass") as Class).id); 
// output undefined if private : the value if public. But don't throw compile time Error. 
(getDefinitionByName("Superclass") as Class).foo(); 
// Call static foo() from Superclass. // Throw a compile time Error if method is private 
相關問題