问题
I have a class which at the moment is quite messy/repetitive:
public class AvFramework extends Object
{
// vars
private var _handler:AvHandler;
private var _keyboard:AvKeyboard;
private var _manager:AvManager;
/**
* Constructor
*/
public function AvFramework()
{
_handler = new AvHandler();
_keyboard = new AvKeyboard();
_manager = new AvManager();
// attach
_handler.framework = this;
_keyboard.framework = this;
_manager.framework = this;
}
/**
* Getters
*/
public function get keyboard():AvKeyboard{ return _keyboard; }
public function get manager():AvManager{ return _manager; }
}
This class is only going to need to make use of more and more classes, and I don't really want to have 3 huge lists for this like above.
Is there a way to do the above dynamically - maybe using getDefinitonByName()
in a loop of strings to represent the classes I want to create.
I also want the properties to be read-only and to be accessed via framework.myDynamicVarHere
.
I'm thinking something along these lines:
- I create a list of the classes I want to create instances of, paired with the variable name they should be accessed by.
- I will need to make the class
dynamic
so that I can set the vars viathis["var"] = new Blah();
Quick snippet of where my thoughts are going:
var required:Object =
{
keyboard: "avian.framework.background.AvKeyboard",
manager: "avian.framework.background.AvManager",
handler: "avian.framework.background.AvHandler"
};
var i:String;
for(i in required)
{
var Req:Class = Class(getDefinitionByName(required[i]));
this[i] = new Req();
AvFrameworkObject(this[i]).framework = this;
}
Just not sure how I would be able to make these read-only.
回答1:
You can use Proxy class to control get/set call and complete Eugeny89 answer. Look at http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html or http://blog.joa-ebert.com/2007/05/25/as3-proxy-example/
var required:Object =
{
keyboard: "avian.framework.background.AvKeyboard",
manager: "avian.framework.background.AvManager",
handler: "avian.framework.background.AvHandler"
};
...
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public dynamic class AvFramework extends Proxy {
private var holder: Object = {};
public function AvFramework() {
var i:String;
for(i in required)
{
var Req:Class = Class(getDefinitionByName(required[i]));
var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard
holder[name] = new Req();
holder[name].framework = this;
}
}
flash_proxy override function getProperty( name: * ): *
{
return holder[name];
}
flash_proxy function setProperty(name:*, value:*):void
{
// Do nothing
}
}
With this code, when you do myAvFrameworkObj.something, getProperty() is automaticaly call and you get property name from "name" variable.
回答2:
Maybe you'll try to wrap that long list of classws in object:
var required:Object =
{
keyboard: "avian.framework.background.AvKeyboard",
manager: "avian.framework.background.AvManager",
handler: "avian.framework.background.AvHandler"
};
...
public class AvFramework extends Object {
private var holder: Object;
public function AvFramework() {
holder = new Object();
var i:String;
for(i in required)
{
var Req:Class = Class(getDefinitionByName(required[i]));
var name = //get Class name from required[i] e.g. AvKeyboard from avian.framework.background.AvKeyboard
holder[name] = new Req();
holder[name].framework = this;
}
}
public var getHolder() { return holder; }
}
You can refer to e.g. AvKeyboard
by framework.getHolder()["AvKeyboard"]
or even by framework.getHolder()[someVar]
. So all this classes from required
are read-only, as holder
is read-only.
Hope that'll help you!
来源:https://stackoverflow.com/questions/6222713/creating-multiple-read-only-properties-dynamically-in-as3