好的。这不是最漂亮的解决方案,但它会起作用。基本上,对于每个“AbstractX”接口(将“X”替换为其他内容),您需要创建两个包装类:“ImportX”和“ExportX”。 ExportX的目标是成功地将AbstractX扩展为Object类型,方法是封装AbstractX,提供与AbstractX类型相同的所有方法,但仅使用内置/预定义的数据类型或数据类型,这些类型或数据类型是其签名中的Flash的一部分。ImportX的目标是缩小与AbstractX类型具有相同特征的动态加载对象(但无法转换为输入AbstractX,并且不能识别为AbstractX类型),但其类型为Object的类型为AbstractX接口。 ExportX和ImportX都使用ImportY,ImportZ等;然而,ExportX使用ImportY,ImportZ等来包装参数,将它委托给AbstractX类型的对象,而ImportX使用它们来包装返回值,这是通过委托给Object类型的对象而产生的。为了使这个多一点理解,我提出下面的例子:
public interface AbstractX
{
// The export/import functions are mandatory
// for all such interfaces. They allow
// for the wrappers to be correctly manipulated.
function export() : Object;
function original() : Object;
// The interface functions vary from
// interface to interface. They can
// be called something much more appropriate.
function interfaceFunction1(param : AbstractY) : AbstractZ;
function interfaceFunction2(param : AbstractA) : AbstractB;
}
// A class of type Import_ always implements Abstract_
public class ImportX implements AbstractX
{
// The constructor for an Import_ Object
// is always of type Object.
public function ImportX(obj : Object) : void {
_loadedobj = obj;
_exportobj = obj.export();
}
// Every Import_ class must implement a similar "wrap" function:
public static function wrap(obj : Object) : AbstractX {
var result : AbstractX = null;
if (obj != null){
if (obj is AbstractX){ // Don't wrap if convertible, directly.
result = obj as AbstractX;
}else if (obj.original() is AbstractX){ // Don't double wrap
result = obj.original() as AbstractX;
}else{
// Needs to be wrapped.
result = new ImportX(obj);
}
}
return result;
}
public function export() : Object {
return _exportobj;
}
public function original() : Object {
return _loadedobj;
}
// For the interface functions, we delegate to _exportobj
// and we wrap the return values, but not the parameters.
public function interfaceFunction1(param : AbstractY) : AbstractZ {
return AbstractZ.wrap(_exportobj.interfaceFunction1(param));
}
public function interfaceFunction2(param : AbstractA) : AbstractB {
return AbstractB.wrap(_exportobj.interfaceFunction2(param));
}
private var _loadedobj : Object;
private var _exportobj : Object;
}
// Although an Export_ object provides SIMILAR methods to type Abstract_,
// the signatures need to be changed so that only builtin/predefined types
// appear. Thus Export_ NEVER implements Abstract_.
public class ExportX
{
// The constructor to Export_ always takes an object of type Abstract_
public function ExportX(obj : AbstractX) : void {
_obj = obj;
}
public function original() : Object {
return _obj;
}
public function export() : Object {
return this;
}
// For the interface functions, we delegate to _obj
// and we wrap the parameters, not the return values.
// Also note the change in signature.
public function interfaceFunction1(param : Object) : Object {
return _obj.interfaceFunction1(AbstractY.wrap(param));
}
public function interfaceFunction2(param : Object) : Object {
return _obj.interfaceFunction2(AbstractA.wrap(param));
}
private var _obj : AbstractX = null;
}
// The definition of class X can occur in and be loaded by any module.
public class X implements AbstractX
{
public function X(/* ... */) : void {
//...
}
public function export() : Object {
if (! _export){
_export = new ExportX(this);
}
return _export;
}
public function original() : Object {
return this;
}
public function interfaceFunction1(param : AbstractY) : AbstractZ {
// ...
}
public function interfaceFunction2(param : AbstractA) : AbstractB {
// ...
}
private var _export : Object = null;
}
// Ok. So here is how you use this...
var classx : Class = dynamicallyLoadClassFromModule("X","module.swf");
var untypedx : Object = new classx();
var typedx : AbstractX = ImportX.wrap(untypedx);
// Use typedx ...
注意:“dynamicallyLoadClassFromModule”不存在。你必须创建它。这仅用于说明目的。 – 2009-07-19 03:11:23
这是测试和工作。不幸的是,每个动态加载的类都需要3个额外的类/接口。如果有更好的,可靠的方法来做到这一点,我会有兴趣听到它。 – 2009-07-19 03:12:23