2

確かに、Ancestor クラスには (例として) "foo" という関数があります。

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

3 に答える 3

1

プロパティを使用してインスタンス自体のクラスへの参照を取得できますがconstructor、祖先クラスにアクセスするには、とを使用する必要がdescribeTypeありgetDefinitionByNameます。これらは強力ですが、コストがかかるため、これを使いすぎないように注意してください。

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( extend.@type.toString().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( extend.@type.toString().replace( "::", "." ) ) as Class;
    return clazz[staticMethod] ? clazz[staticMethod] : undefined;
}
于 2012-05-10T07:19:52.677 に答える
0

または(Sam DeHaanの回答に基づく):

Superclass と Descendant の両方に 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
于 2012-05-12T12:06:28.240 に答える