2010年2月15日 星期一

測試ActionScript 3 Object Class



先測試Object.prototype

ClassOne.as


package tw.right929
{
    public dynamic class ClassOne
    {
        public var name:String    =    "one";
       
        public function ClassOne()
        {
        }
       
        public function showName():String
        {
            return "my name is "+name;
        }
    }
}

ClassTwo.as


package tw.right929
{
    public dynamic class ClassTwo extends ClassOne
    {
        public function ClassTwo()
        {
        }
    }
}

ClassThree.as


package tw.right929
{
    public dynamic class ClassThree extends ClassOne
    {
        public function ClassThree()
        {
            super();
        }
    }
}


TestObject.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 tw.right929.*;
            private function init():void
            {
                trace(ClassOne.prototype);//[object Object]
                trace(ClassTwo.prototype);//[object Object]
                trace(ClassThree.prototype);//[object Object]
                trace(Object.prototype);//[object Object]
                trace(ClassOne.prototype == Object.prototype);//false
                trace(ClassThree.prototype == ClassTwo.prototype);//false
            }
        ]]>
    </fx:Script>
</s:Application>

由結果可知prototype和使用extends所宣告的繼承完全沒有關係。
每個Object.prototype都是各別獨立的Object。

透過Object.prototype動態幫所有Object的子類別加上方法。
修改TestObject.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 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 obj:Object    =    new Object();
                trace(obj.getClassName());//Object
               
                var one:ClassOne    =    new ClassOne();
                trace(one.getClassName());//tw.right929::ClassOne
               
                var two:ClassTwo    =    new ClassTwo();
                trace(two.getClassName());//[ClassTwo] tw.right929::ClassTwo
               
                var sprite:Sprite    =    new Sprite();
                trace(Object(sprite).getClassName());//flash.display::Sprite
            }
        ]]>
    </fx:Script>
</s:Application>


可以看到prototype的覆寫也運作正常。
若把ClassOne~Three的dynamic拿掉會因為找不到這個方法而無法通過編譯,
這時就要像Sprite一樣,才轉型成Object再呼叫getClassName。

修改ClassOne加上getClassName()


package tw.right929
{
    public dynamic class ClassOne
    {
        import flash.utils.*;
       
        public var name:String    =    "one";
       
        public function ClassOne()
        {
        }
       
        public function showName():String
        {
            return "my name is "+name;
        }
       
        public function getClassName():String
        {
            return "[ClassOne] "+flash.utils.getQualifiedClassName(this);
        }
    }
}

執行結果

Object
[ClassOne] tw.right929::ClassOne
[ClassOne] tw.right929::ClassTwo
flash.display::Sprite
由結果可知以function宣告的方法優先序高於prototype,
因為要執行那個方法是先搜尋完繼承鏈後,才會去找prototype中的方法。
這個規則用var宣告的變數亦同。


測試是否可以動態改變prototype,好達到動態改變繼承鏈。
修改TestObject.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 tw.right929.*;
            private function init():void
            {
                var obj:Object    =    new Object();
                var one:ClassOne    =    new ClassOne();
                var two:ClassTwo    =    new ClassTwo();
                var three:ClassThree    =    new ClassThree();
                
                Object.prototype    =    one;//發生錯誤,屬性唯讀。
                trace(obj.showName());
            }
        ]]>
    </fx:Script>
</s:Application>

可惜prototype屬性是唯讀的。
參考:

沒有留言:

張貼留言

追蹤者