2010年2月15日 星期一

測試ActionScript 3 的反射機制



測試ActionScript 3 Object Class
先看看類別和實例的差別
TestDescribeType.mxml



<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="init()" xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
    <fx:Script>
        <![CDATA[
            import flash.utils.*;
           
            import tw.right929.*;
           
            private function init():void
            {
                trace(flash.utils.describeType(ClassOne));
                /*
                <type name="tw.right929::ClassOne" base="Class" isDynamic="true" isFinal="true" isStatic="true">
                <extendsClass type="Class"/>
                <extendsClass type="Object"/>
                <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
                <factory type="tw.right929::ClassOne">
                <extendsClass type="Object"/>
                <variable name="name" type="String"></variable>
                <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                <method name="showName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                </factory>
                </type>
                */
                trace(flash.utils.describeType(new ClassOne()));
                /*
                <type name="tw.right929::ClassOne" base="Object" isDynamic="true" isFinal="false" isStatic="false">
                <extendsClass type="Object"/>
                <variable name="name" type="String"></variable>
                <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                <method name="showName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                </type>
                */
            }
        ]]>
    </fx:Script>
</s:Application>



修改CalssOne,加入getter、setter和protected參數



package tw.right929
{
    import flash.display.Sprite;

    public dynamic class ClassOne
    {
        import flash.utils.*;
       
        public var name:String    =    "one";
        private var _getAndSet:int;
        private var _getO:Sprite;
        private var _setO:ClassTwo;
        protected var protectedO:Array;
       
        public function ClassOne()
        {
        }
       
        public function showName():String
        {
            return "my name is "+name;
        }
       
        public function getClassName():String
        {
            return "[ClassOne] "+flash.utils.getQualifiedClassName(this);
        }
       
        public function get getAndSet():int
        {
            return _getAndSet;
        }
       
        public function set getAndSet(v:int):void
        {
            _getAndSet    =    v;
        }
       
        public function set setO(v:Sprite):void
        {
            _getO    =    v;
        }
       
        public function get getO():ClassTwo
        {
            return _setO;
        }
    }
}

修改TestDescribeType.mxml



<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="init()" xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
    <fx:Script>
        <![CDATA[
            import flash.utils.*;
           
            import tw.right929.*;
           
            private function init():void
            {
                Object.prototype.getClassName    =    function ():String
                {
                    return flash.utils.getQualifiedClassName(this);
                };
               
                ClassTwo.prototype.getClassName    =    function ():String
                {
                    return "[ClassTwo] "+flash.utils.getQualifiedClassName(this);
                };
               
                var two:ClassTwo    =    new ClassTwo();
                two.temp    =    "this is temp";
               
                trace(flash.utils.describeType(ClassOne));
                /*
                <type name="tw.right929::ClassOne" base="Class" isDynamic="true" isFinal="true" isStatic="true">
                    <extendsClass type="Class"/>
                    <extendsClass type="Object"/>
                    <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
                    <factory type="tw.right929::ClassOne">
                        <extendsClass type="Object"/>
                        <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                        <accessor name="getAndSet" access="readwrite" type="int" declaredBy="tw.right929::ClassOne"></accessor>
                        <method name="showName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                        <variable name="name" type="String"></variable>
                        <accessor name="getO" access="readonly" type="tw.right929::ClassTwo" declaredBy="tw.right929::ClassOne"></accessor>
                        <accessor name="setO" access="writeonly" type="flash.display::Sprite" declaredBy="tw.right929::ClassOne"></accessor>
                    </factory>
                </type>
                */
                trace(flash.utils.describeType(new ClassOne()));
                /*
                <type name="tw.right929::ClassOne" base="Object" isDynamic="true" isFinal="false" isStatic="false">
                    <extendsClass type="Object"/>
                    <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                    <accessor name="getAndSet" access="readwrite" type="int" declaredBy="tw.right929::ClassOne"></accessor>
                    <method name="showName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                    <variable name="name" type="String"></variable>
                    <accessor name="getO" access="readonly" type="tw.right929::ClassTwo" declaredBy="tw.right929::ClassOne"></accessor>
                    <accessor name="setO" access="writeonly" type="flash.display::Sprite" declaredBy="tw.right929::ClassOne"></accessor>
                </type>
                */
                trace(flash.utils.describeType(ClassTwo));
                /*
                <type name="tw.right929::ClassTwo" base="Class" isDynamic="true" isFinal="true" isStatic="true">
                    <extendsClass type="Class"/>
                    <extendsClass type="Object"/>
                    <accessor name="prototype" access="readonly" type="*" declaredBy="Class"/>
                    <factory type="tw.right929::ClassTwo">
                        <extendsClass type="tw.right929::ClassOne"/>
                        <extendsClass type="Object"/>
                        <method name="showName" declaredBy="tw.right929::ClassTwo" returnType="String"></method>
                        <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                        <accessor name="getAndSet" access="readwrite" type="int" declaredBy="tw.right929::ClassOne"></accessor>
                        <variable name="name" type="String"></variable>
                        <accessor name="getO" access="readonly" type="tw.right929::ClassTwo" declaredBy="tw.right929::ClassOne"></accessor>
                        <accessor name="setO" access="writeonly" type="flash.display::Sprite" declaredBy="tw.right929::ClassOne"></accessor>
                    </factory>
                </type>
                */
               
                trace(flash.utils.describeType(two))
                /*
                <type name="tw.right929::ClassTwo" base="tw.right929::ClassOne" isDynamic="true" isFinal="false" isStatic="false">
                    <extendsClass type="tw.right929::ClassOne"/>
                    <extendsClass type="Object"/>
                    <method name="showName" declaredBy="tw.right929::ClassTwo" returnType="String"></method>
                    <method name="getClassName" declaredBy="tw.right929::ClassOne" returnType="String"></method>
                    <accessor name="getAndSet" access="readwrite" type="int" declaredBy="tw.right929::ClassOne"></accessor>
                    <variable name="name" type="String"></variable>
                    <accessor name="getO" access="readonly" type="tw.right929::ClassTwo" declaredBy="tw.right929::ClassOne"></accessor>
                    <accessor name="setO" access="writeonly" type="flash.display::Sprite" declaredBy="tw.right929::ClassOne"></accessor>
                </type>
                */
            }
        ]]>
    </fx:Script>
</s:Application>


由結果可知,下面條列的物件無法透過flash.utils.describeType取得


  1. 動態加入的參數、方法
  2. protected、private的屬性、方法





若是使用flex測試,會發現有metadata的tag,這個是flex動態寫進去的,
常用的有[Event] [Bindable] [Style]等,
也可以自訂metadata tag。

沒有留言:

張貼留言

追蹤者