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

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 对象具有 Class 的所有静态属性和方法,因此这应该是可靠的。cl.foo返回一个 Function 对象,然后您可以.call()

于 2012-05-11T13:05:12.397 回答
1

您可以使用该constructor属性获取对实例自己的类的引用,但要访问祖先类,您必须使用describeTypeand 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 回答