先測試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
可以看到prototype的覆寫也運作正常。
<?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()
執行結果
Object
[ClassOne] tw.right929::ClassOne
[ClassOne] tw.right929::ClassTwo
flash.display::Sprite
由結果可知以function宣告的方法優先序高於prototype,
因為要執行那個方法是先搜尋完繼承鏈後,才會去找prototype中的方法。
這個規則用var宣告的變數亦同。
這時就要像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屬性是唯讀的。
參考:
沒有留言:
張貼留言