好的。這不是最漂亮的解決方案,但它會起作用。基本上,對於每個「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