2012-05-10 17 views
2

Ancestorクラスは、実際には(たとえば、)「foo」と呼ばれる関数を持っています。 ancestorClassを調べる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.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(); 

Classオブジェクトは、静的プロパティとメソッドのすべてを持っていますこのクラスは信頼できるはずです。 cl.fooは、.call()のできるFunctionオブジェクトを返します。

(サムDeHaanの回答者に基づいて)
+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

または:

スーパークラスと子孫が両方の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 
関連する問題