Ok。これは最も美しい解決策ではありませんが、うまくいきます。基本的に、すべてのインターフェイス "AbstractX" ("X" を別のものに置き換えます) に対して、"ImportX" と "ExportX" の 2 つのラッパー クラスを作成する必要があります。ExportX の目標は、AbstractX をラップすることによって、AbstractX を Object 型に正常に拡張し、AbstractX 型と同じメソッドをすべて提供することですが、組み込み/定義済みのデータ型またはシグネチャのフラッシュの一部であるデータ型のみを使用することです。ImportX の目的は、AbstractX 型と同じ特性 (ただし、AbstractX 型にキャストできず、AbstractX 型として認識されない) で動的に読み込まれるオブジェクトを、AbstractX インターフェイスの Object 型に絞り込むことです。ExportX と ImportX はどちらも ImportY、ImportZ などを使用します。ただし、ExportX は ImportY、ImportZ などを使用します。パラメーターをラップして、AbstractX 型のオブジェクトに委譲する一方で、ImportX はそれらを使用して、Object 型のオブジェクトに委譲することから生じる戻り値をラップします。これをもう少しわかりやすくするために、次の例を示します。
パブリック インターフェイス AbstractX
{
// export/import 関数は必須です
// そのようなすべてのインターフェース。彼らは許可します
// ラッパーが正しく操作されるようにします。
関数 export() : オブジェクト;
関数 original() : オブジェクト;
// インターフェイス関数は次のように異なります
// インターフェイスからインターフェイスへ。彼らはできる
// より適切な呼び方。
関数 interfaceFunction1(param : AbstractY) : AbstractZ;
関数 interfaceFunction2(param : AbstractA) : AbstractB;
}
// Import_ 型のクラスは常に Abstract_ を実装します
public クラス ImportX は AbstractX を実装します
{
// Import_ Object のコンストラクタ
// 常に Object 型です。
public function ImportX(obj : Object) : void {
_loadedobj = obj;
_exportobj = obj.export();
}
// すべての Import_ クラスは、同様の「ラップ」関数を実装する必要があります:
public static function wrap(obj : Object) : AbstractX {
var 結果: AbstractX = null;
if ( obj != null ){
if ( obj is AbstractX ){ // 変換可能な場合は直接ラップしないでください。
結果 = obj as AbstractX;
}else if ( obj.original() is AbstractX ){ // 二重ラップしない
結果 = obj.original() as AbstractX;
}そうしないと{
// ラップする必要があります。
結果 = 新しい ImportX(obj);
}
}
結果を返します。
}
public function export() : オブジェクト {
_exportobj を返します。
}
public function original() : オブジェクト {
_loadedobj を返します。
}
// インターフェイス関数については、_exportobj に委譲します
// 戻り値をラップしますが、パラメーターはラップしません。
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 : オブジェクト;
private var _exportobj : オブジェクト;
}
// Export_ オブジェクトは Abstract_ 型と同様のメソッドを提供しますが、
// シグニチャを変更して、組み込み/定義済みの型のみを使用できるようにする必要があります
// 現れる。したがって、Export_ は Abstract_ を実装しません。
パブリック クラス ExportX
{
// Export_ のコンストラクタは、常に Abstract_ 型のオブジェクトを取ります
public function ExportX(obj : AbstractX) : void {
_obj = obj;
}
public function original() : オブジェクト {
_obj を返します。
}
public function export() : オブジェクト {
これを返します。
}
// インターフェイス関数については、_obj にデリゲートします
// 戻り値ではなく、パラメータをラップします。
// 署名の変更にも注意してください。
public function interfaceFunction1(param : Object) : オブジェクト {
return _obj.interfaceFunction1(AbstractY.wrap(param));
}
public function interfaceFunction2(param : Object) : オブジェクト {
return _obj.interfaceFunction2(AbstractA.wrap(param));
}
プライベート var _obj : AbstractX = null;
}
// クラス X の定義は、任意のモジュールで発生し、ロードされる可能性があります。
public class X は AbstractX を実装します
{
public function X( /* ... */ ) : void {
//...
}
public function export() : オブジェクト {
if ( ! _export ){
_export = 新しい ExportX(これ);
}
_エクスポートを返します。
}
public function original() : オブジェクト {
これを返します。
}
public function interfaceFunction1(param : AbstractY) : AbstractZ {
// ...
}
public function interfaceFunction2(param : AbstractA) : AbstractB {
// ...
}
プライベート var _export : オブジェクト = null;
}
// Ok。では、これをどう使うかというと…
var classx : Class = dynamicLoadClassFromModule("X","module.swf");
var untypedx : Object = new classx();
var typedx : AbstractX = ImportX.wrap(untypedx);
// typedx を使用 ...