我有一种方法,每次调用时都会记录一条消息。我希望这条日志消息指出该方法是直接调用还是在子类中使用super
调用。
class DoerOfWork {
public function doWork():void {
var calledWithSuper:Boolean;
calledWithSuper = ???;
trace("doWork called" + (calledWithSuper ? " (with super)." : "."));
}
}
class SlowerDoerOfWork extends DoerOfWork {
public override function doWork():void {
for (var i:Number = 0; i < 321684; i++) {
// wait a moment
}
super.doWork();
}
}
我希望通过比较this
和doWork
来确定this.doWork
的班级是否覆盖了DoerOfWork.prototype.doWork
的实施。
不幸的是,这是不可能的。在ActionScript中的任何地方都无法访问未绑定的方法(规范列出了两种类型的函数:函数闭包和绑定方法)。在MethodClosure
上的实例上甚至没有任何属性可以识别两个是否是同一方法的绑定副本。
如何检查方法是否已被覆盖或使用任何其他方法来确定当前正在执行的ActionScript方法是使用super
调用还是直接调用?
答案 0 :(得分:3)
您可以将当前正在执行的函数的引用作为arguments.callee
。从该方法开始,这将是MethodClosure
DoerOfWork().doWork()
和this
。如果doWork()
未被覆盖,则等于this.doWork
。
class DoerOfWork {
public function doWork():void {
var calledWithSuper:Boolean;
calledWithSuper = this.doWork == arguments.callee;
trace("doWork called" + (calledWithSuper ? " (with super)." : "."));
}
}
如果您在非严格模式下运行,显然这将禁用当前函数的参数计数检查。 (我自己没有检查过,我甚至不确定如何在IntelliJ中禁用严格模式。)
答案 1 :(得分:3)
如果您愿意使用flash.utils.describeType()
,它会包含我们需要的信息:
<type name="Main.as$1::SlowerDoerOfWork" base="Main.as$1::DoerOfWork"
isDynamic="false" isFinal="false" isStatic="false">
<extendsClass type="Main.as$1::DoerOfWork"/>
<extendsClass type="Object"/>
<method name="doWork" declaredBy="Main.as$1::SlowerDoerOfWork"
returnType="void">
<metadata name="__go_to_definition_help">
<arg key="pos" value="1170"/>
</metadata>
</method>
<metadata name="__go_to_definition_help">
<arg key="pos" value="1103"/>
</metadata>
</type>
XML中每个declaredBy
的{{1}}属性使用与<method>
相同的格式,我们可以比较这些属性以确定我们的实现是否被覆盖。
flash.utils.getQualifiedClassName