AdvancedObject
package tw.right929
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
use namespace flash_proxy
public dynamic class AdvancedObject extends Proxy
{
/**
* 統一改變這個屬於這個類別物件的missFunction
*/
public static var missFunction:Function = function (name:*, rest:Array):* {return undefined};
/**
* 統一改變這個屬於這個類別物件的missProperty
*/
public static var missProperty:Function = function (name:*):* {return undefined};
private var _obj:Object = new Object();
private var _properties:Array = new Array();
private var _needUpdateProperties:Boolean = false;
private var _superObj:Object;
private var _missFunction:Function;
private var _missProperty:Function;
public function AdvancedObject()
{
super();
}
/**
* 設定父物件。
*/
public final function set superObj(v:Object):void
{
_superObj = v;
}
public final function get superObj():Object
{
return _superObj;
}
/**
* 若呼叫了不存在的方法,則會呼叫這個方法,預設值是傳回undefined。
*/
public final function set missFunction(v:Function):void
{
_missFunction = v;
}
public final function get missFunction():Function
{
if(_missFunction)
return _missFunction;
return getDefinitionByName(getQualifiedClassName(this))["missFunction"] as Function;
}
/**
* 若想取得不存在的屬性,則會呼叫這個方法,預設值是傳回undefined。
*/
public final function set missProperty(v:Function):void
{
_missProperty = v;
}
public final function get missProperty():Function
{
if(_missProperty)
return _missProperty;
return getDefinitionByName(getQualifiedClassName(this))["missProperty"] as Function;
}
/**
* 先看自已有沒有這個方法,若沒有呼叫superObj的,若superObj也沒有,統一呼叫這個物件的missFunction。
*/
override flash_proxy function callProperty(name:*, ... rest):*
{
if(_hasProperty(name))
return _obj[name].apply(this , rest);
else if(_superObj && _superObj.hasOwnProperty(name))
return _superObj[name].apply(this , rest);
else
return missFunction(name , rest);
}
/**
* 這個方法應該要只能刪掉自已的,不能刪掉繼承鏈上的屬性。
*/
override flash_proxy function deleteProperty(name:*):Boolean
{
_needUpdateProperties = true;
return delete _obj[name];
}
override flash_proxy function getDescendants(name:*):*
{
return _obj[name];
}
/**
* 先看自已有沒有這個屬性,若沒有找superObj的,若superObj也沒有,統一呼叫這個物件的missProperty。
*/
override flash_proxy function getProperty(name:*):*
{
if(_hasProperty(name))
return _obj[name];
else if(_superObj && _superObj.hasOwnProperty(name))
return _superObj[name];
else
return missProperty(name);
}
/**
* 尋找是否有這個屬性,包含superObj。
*/
override flash_proxy function hasProperty(name:*):Boolean
{
updateProperties();
if(_hasProperty(name))
return true;
else if(_superObj && _superObj.hasOwnProperty(name))
return true;
else
return false;
}
/**
* 尋找是否有這個屬性,不包含superObj。
*/
private function _hasProperty(name:*):Boolean
{
if(name is QName)
name = name.localName;
return(name in _obj);
}
override flash_proxy function isAttribute(name:*):Boolean
{
return true;
}
override flash_proxy function nextName(index:int):String
{
updateProperties();
return _properties[index-1].toString();
}
override flash_proxy function nextNameIndex(index:int):int
{
updateProperties()
if (index < _properties.length)
return index + 1;
else
return 0;
}
override flash_proxy function nextValue(index:int):*
{
updateProperties();
return _obj[_properties[index-1]];
}
/**
* 先看自已有沒有這個屬性,若沒有找superObj的,若superObj也沒有,幫自已新增這個屬性。
*/
override flash_proxy function setProperty(name:*, value:*):void
{
_needUpdateProperties = true;
if(_hasProperty(name))
_obj[name] = value;
else if(_superObj && _superObj.hasOwnProperty(name))
_superObj[name] = value;
else
_obj[name] = value;
}
/**
* 重整自已的屬性清單。
*/
private function updateProperties():void
{
if(_needUpdateProperties)
{
_properties = new Array();
for (var p:String in _obj)
_properties.push(p);
_needUpdateProperties = false;
}
}
}
}
這個類別的功能尚未完備,僅是為了測試而生。
TestDynamicInheritance.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.display.*;
import tw.right929.AdvancedObject;
private function init():void
{
var classOne:AdvancedObject = new AdvancedObject();
classOne.name = "classOne name";
var classTwo:AdvancedObject = new AdvancedObject();
classTwo.showName = function ():String
{
return "classTwo showName "+this.name;
};
var classThree:AdvancedObject = new AdvancedObject();
classThree.showName = function ():String
{
return "classThree showName "+this.name;
};
trace(classOne.showName());//undefined
trace(classTwo.showName());//classTwo showName undefined
trace(classThree.showName());//classThree showName undefined
classTwo.superObj = classOne;
classThree.superObj = classTwo;
trace(classTwo.showName());//classTwo showName classOne name
trace(classThree.showName());//classThree showName classOne name
classTwo.name = "two";
trace(classOne.name);//two
trace(classTwo.showName());//classTwo showName two
trace(classThree.showName());//classThree showName two
//因為two和three的父類別都是one,而改了two的name會去變動one的name,所以three的name也會跟著變動。
classTwo.superObj = null;
classThree.superObj = null;
trace(classTwo.showName());//classTwo showName undefined
trace(classThree.showName());//classThree showName undefined
//脫離繼承關係後,連name的屬性也跟著消失。
classThree.name = "three";
classTwo.superObj = classOne;
classThree.superObj = classTwo;
trace(classTwo.showName());//classTwo showName two
trace(classThree.showName());//classThree showName three
//three因為在沒繼承的關係下,新增了name屬性,所以three的name屬性蓋掉了two的name屬性。
classOne.superObj = classThree;
trace(classOne.showName());//classThree showName two
trace(classTwo.showName());//classTwo showName two
trace(classThree.showName());//classThree showName three
//循環繼承,one因為自已沒有showName方法,所以去呼叫他的父類別three的showName方法,然後套上自已所有的name。
//這裡有個風險,若是指定一個沒有在繼承圈中的屬性或方法,就會無限迴圈了。
classThree.superObj = null;
classThree.missFunction = function (name:*, rest:Array):*
{
var temp:String = name.toString()
if(temp.indexOf("create_") == 0)
{
temp = temp.substr(7).replace(/_/g , ".")
var c:Class = flash.utils.getDefinitionByName(temp) as Class;
var r:Object = new c();
if(rest.length > 0)
{
var data:Object = rest[0]
for(var p:String in data)
r[p] = data[p];
}
return r;
}
return undefined;
};
var s:Sprite = classThree.create_flash_display_Sprite({x:10 , y:100 , rotationX:20 , rotationY:200}) as Sprite;
trace(s.x+" "+s.y+" "+s.rotationX+" "+s.rotationY);//10 100 20 200
var classZero:AdvancedObject = classThree.create_tw_right929_AdvancedObject
(
{
superObj:classThree ,
name:"zero" ,
myClass:function ():String {return flash.utils.getQualifiedClassName(this)}
}
) as AdvancedObject;
trace(classZero.showName());//classThree showName zero
trace(classZero.myClass());//tw.right929::AdvancedObject
classTwo.superObj = classZero;
trace(classTwo.showName());//classTwo showName zero
trace(classTwo.myClass());//tw.right929::AdvancedObject
}
]]>
</fx:Script>
</s:Application>
初步測試正常,只有在循環繼承中若指定不存在的屬性和方法會產生無限迴圈。
接下來再來做一件更有趣的事
修改TestDynamicInheritance.mxml,在最後加上
private var _thisName:String = "thisName";
classTwo.showName = function ():String
{
_thisName = "new thisName";
return "classTwo showName "+_thisName;
};
trace(classTwo.showName());//classTwo showName new thisName
trace(_thisName);//new thisName
注意到,傳進去給classTwo.showName的function中,我們修改了private的變數,並指定為新值。就上面的例子來說,
在function中的this._thisName是undefined,而_thisName則是"thisName",
在function中的this.name是"two",而name則是"TestDynamicInheritance0"。
沒有留言:
張貼留言