确定是否使用super调用ActionScript方法

时间:2013-03-05 01:22:16

标签: actionscript-3 super

我有一种方法,每次调用时都会记录一条消息。我希望这条日志消息指出该方法是直接调用还是在子类中使用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();
    }
}

我希望通过比较thisdoWork来确定this.doWork的班级是否覆盖了DoerOfWork.prototype.doWork的实施。

不幸的是,这是不可能的。在ActionScript中的任何地方都无法访问未绑定的方法(规范列出了两种类型的函数:函数闭包和绑定方法)。在MethodClosure上的实例上甚至没有任何属性可以识别两个是否是同一方法的绑定副本。

如何检查方法是否已被覆盖或使用任何其他方法来确定当前正在执行的ActionScript方法是使用super调用还是直接调用?

2 个答案:

答案 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