2013-03-05 14 views
6

Tôi có phương thức ghi lại thư mỗi khi được gọi. Tôi muốn thông điệp tường trình này để cho biết liệu phương pháp được gọi trực tiếp hoặc được gọi bằng cách sử dụng super trong một lớp con.Xác định xem phương pháp ActionScript có được gọi là sử dụng siêu

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(); 
    } 
} 

Tôi hy vọng nó sẽ có thể để xác định xem loại this đã ghi đè thi hành doWork bằng cách so sánh this.doWork-DoerOfWork.prototype.doWork.

Rất tiếc, điều này là không thể. Các phương thức Unbound không thể truy cập được ở bất cứ nơi nào trong ActionScript (đặc tả này liệt kê hai loại hàm: đóng các hàm và các phương thức liên kết). Thậm chí không có bất kỳ thuộc tính nào trên các cá thể trên MethodClosure có thể xác định xem hai bản sao có bị ràng buộc của cùng một phương thức hay không.

Làm cách nào để kiểm tra xem phương thức đã bị ghi đè hay sử dụng bất kỳ phương pháp nào khác để xác định xem phương pháp ActionScript hiện đang thực hiện được gọi là sử dụng super hoặc được gọi trực tiếp?

Trả lời

3

Bạn có thể tham chiếu đến chức năng hiện đang thi hành là arguments.callee. Từ phương thức này, đây sẽ là MethodClosure của DoerOfWork().doWork() với this. Nếu doWork() không bị ghi đè, giá trị này sẽ bằng this.doWork.

class DoerOfWork { 
    public function doWork():void { 
     var calledWithSuper:Boolean; 

     calledWithSuper = this.doWork == arguments.callee; 

     trace("doWork called" + (calledWithSuper ? " (with super)." : ".")); 
    } 
} 

Nếu bạn đang chạy ở chế độ không nghiêm ngặt, dường như điều này sẽ vô hiệu hóa tính năng kiểm tra đối số cho hàm hiện tại. (. Tôi đã không kiểm tra này bản thân mình, tôi thậm chí không chắc chắn làm thế nào để vô hiệu hóa chế độ nghiêm ngặt trong IntelliJ)

3

Nếu bạn sẵn sàng để sử dụng flash.utils.describeType(), nó chứa các thông tin chúng ta cần:

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

Thuộc tính declaredBy của mỗi <method> trong XML sử dụng định dạng giống như flash.utils.getQualifiedClassName và chúng tôi có thể so sánh chúng để xác định xem việc triển khai của chúng tôi có bị ghi đè hay không.

class DoerOfWork { 
    public function doWork():void { 
     var calledWithSuper:Boolean; 

     var currentImplementationFrom:String 
      = flash.utils.describeType(this).method.(@name=="doWork")[email protected]; 
     var thisImplementationFrom:String 
      = flash.utils.getQualifiedClassName(DoerOfWork); 

     calledWithSuper = currentImplementationFrom != thisImplementationFrom; 

     trace("doWork called" + (calledWithSuper ? " (with super)." : ".")); 
    } 
}