AS3反射。如何确定方法是否被覆盖?

时间:2009-11-19 01:41:29

标签: actionscript-3 reflection

是否可以使用AS3反射来查明方法是否被覆盖?

我需要一个方法:

protected function isOverriden(methodName:string) : bool
{
    //magic here!
    //...

    return awesomeLocalVariable;
}

因此,我将方法名称作为字符串传递,并且只有当对象具有该名称的方法并且从原始实现中重写时,isOverridden方法才会生成true。

关于如何在那里编写魔法的任何想法?

感谢。

编辑:根据要求,问题的背景:

我正在构建一个用于创建AS3游戏的框架。我想为我的游戏对象提供“组件”,每个组件为其应用的游戏对象提供功能。组件基于事件(onClick,onUpdate,onShapeCollision等)我需要在Component类中使用此代码,因此我只能注册实际的Component派生类实现的事件(覆盖)。

示例组件:

    public class CTrace extends ScriptComponent
    {
            public override function onClick(event:MouseEvent = null):void
            {
                    trace(Owner.Id);
            }
    }

框架应该将onClick方法注册为MouseEvent.CLICK事件的事件处理程序,因为它会覆盖默认实现。

为什么我需要默认实现?因为我希望类覆盖支持的方法,所以如果用户尝试使用不受支持的事件,则会出现编译时错误。

这有意义吗?

2 个答案:

答案 0 :(得分:2)

这是一个尝试。该函数是静态的,它可以用于检查任何类或对象,而不管它实现的类。如果你给它类型,它将使用它,如果你给它一个实例,它将自己获得类型。内部逻辑只是检查我们正在寻找的函数的给定类型描述,如果存在并由类声明,它将检查该方法是否也存在于父类中。如果两者都存在,那就享受吧,这意味着它被覆盖了。

/**
 * Returns true only if the method name given is declared by
 * the source class, and any parent class.
 */
static public function isOverridden(source:*, methodName:String):Boolean {
    var parentTypeName:String = getQualifiedSuperclassName(source);
    if (parentTypeName == null) {
        return false;
    }//if

    var typeName:String = getQualifiedClassName(source);
    var typeDesc:XML = describeType(getDefinitionByName(typeName));
    var methodList:XMLList = typeDesc.factory.method.(@name == methodName);

    if (methodList.length() > 0) {
        //Method exists
        var methodData:XML = methodList[0];
        if (methodData.@declaredBy == typeName) {
            //Method is declared in self
            var parentTypeDesc:XML = describeType(getDefinitionByName(parentTypeName));
            var parentMethodList:XMLList = parentTypeDesc.factory.method.(@name == methodName);
            return parentMethodList.length() > 0;
        }//if
    }//if

    return false;
}//isOverridden

如果需要它,它需要的导入工作:

import flash.utils.describeType;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
import flash.utils.getQualifiedSuperclassName;

使用它:

trace(isOverridden(ChildrenClass, "overriddenMethod")); //true
trace(isOverridden(ChildrenClass, "onlyChildMethod")); //false
trace(isOverridden(ChildrenClass, "onlyParentMethod")); //false

答案 1 :(得分:0)

如果你在同一个对象内部询问,你可以

overriden = (this[stringNameOfMethod] instanceOf Function && super[stringNameOfMethod] instanceOf Function);

如果没有,请尝试使用describeType。检查是否有名称的方法并检查“declaredBy”属性。瞧!

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/utils/package.html#describeType()

抱歉,我正处于从CS3迁移到Flash构建器的过程中,所以现在我无法确保我的想法正常工作。但我会回来的。