是否可以使用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事件的事件处理程序,因为它会覆盖默认实现。
为什么我需要默认实现?因为我希望类覆盖支持的方法,所以如果用户尝试使用不受支持的事件,则会出现编译时错误。
这有意义吗?
答案 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构建器的过程中,所以现在我无法确保我的想法正常工作。但我会回来的。