4月1日ですが、ActionScript3で、Namespaceを使ってオーバーロードをスマートに実現する方法を思いついたので書きます。
今回、ちょっとコードが長いので、FlexBuilder2 Beta2用のプロジェクトをそのまま固めてアップしました。ダウンロードはこちら。これを見ながら読み進めてください。
このプロジェクトには、org.be_interactive.overloadパッケージと、サンプル用のOverload.asが含まれます。
org.be_interactive.overloadパッケージには、
- OverloadExtensionクラス
- 4つのネームスペース
が定義されています。
とりあえず使い方ですが、まず
import org.be_interactive.overload.OverloadExtension; import org.be_interactive.overload.overload_String; import org.be_interactive.overload.overload_Int;
クラスと必要なネームスペースを読み込んで、
class Hoge
{
import flash.util.trace;
overload_String function fuga (str:String) : void
{
trace('String', str);
}
overload_Int function fuga (n:int) : void
{
trace('Int', n);
}
}
引数の型に合わせてネームスペースを変え、同じ関数名でオーバーロード用のメソッドを定義します。そして、
public function fuga (...args) : void
{
OverloadExtension.execute(this, 'fuga', args);
}
実際に呼び出されるpublicメソッドを作り、 OverloadExtension.execute(ターゲット, 呼び出すメソッド名, 引数配列) で呼び出します。これで準備完了。なんとこれだけで、オーバーロードが可能になります。
var h:Hoge = new Hoge();
h.fuga('hello, world'); // 出力:String hello, world
h.fuga(1); // 出力:int 1
但し、デフォルトでは 引数なし/String/Int/String+Int のオーバーロードしかサポートされていないので、これを拡張する方法を紹介します。
まず、オーバーロード用の適切なネームスペースを用意します。ネームスペース名は引数の型を並べるのがいいかと思いますが、実際は何でも構いません。
public namespace overload_String_String = 'http://www.be-interactive.org/OverloadExtension/String/String';
次に、OverloadExtensionクラスにネームスペースを登録します。これは初期化段階で1度呼び出せばOKです(例えばDocumentRootのコンストラクタ)。
OverloadExtension.register(overload_String_String, String, String); // 引数は、(ネームスペースへの参照, Class, Class, ...)
最後に、先ほどと同じようにメソッドを定義すれば完了です。
overload_String_String function fuga (str:String, str2:String) : void
{
trace('StringString', str, str2);
}
デフォルトでは、初期化段階(OverloadExtension#initializer)で次のように4つ登録されています。ここは自由に変更してもらって構いません。
register(overload_default); register(overload_String, String); register(overload_Int, int); register(overload_String_Int, String, int);
OverloadExtensionの実装の説明は省きます。興味がある人はコードを読んでくださいな。ちなみに、このライブラリは自由に使用/改変してもらって構いませんが、できればパッケージは変えないでください。



