In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

引数の異なる初期処理メソッドを共通的に呼び出すコード(バグ有り)

Baseを継承したクラスをManagerに登録することによって、Baseに対して一定の振る舞いをさせるという処理をすることがあると思います。TempleteMethodパターンを使うことも出来ますが、クラス毎に引数の型を変えて呼び出すことが出来ました。

2010/11/8
initializeメソッドを継承先クラスに定義しない場合、例外が発生していました。原因や解決策はTalk欄にて。
Get Adobe Flash player
by asahiufo 08 Nov 2010
  • Related works: 1
  • Talk

    9re at 07 Nov 2010 18:25
    var initFunc:Function = this["initialize"] as Function; if (initFunc == null) { return; } だとthisがinitializeを持たないときに、initFuncがnullになるのではなく、 実行時エラーとなってしまいます。 なので、 if (!("initialize" in this) return; var initFunc:Function = this["initialize"] as Function; のほうが良いように思われます。 実際デバッグ版プレイヤーではSub3のコードは動かないです。 + メソッドをクラスに動的に追加するにはより、ECMA的な書き方が出来ます。 ただしエディタとかの自動補完などの恩恵を受けれないので、その辺はtrade offですが、 設定スクリプトを走らせたいみたいな小粒な目的には良いかもしれません。 http://wonderfl.net/c/r9wF
    asahiufo at 08 Nov 2010 15:05
    ご指摘ありがとうございます。 ブラウザのFlashPlayerがデバッグ版では無く、 エラーが出ていることに気づいていませんでした・・・。 凡ミスでお恥ずかしいです。 initializeの存在をin演算子でチェック出来るんですね。 添削ありがとうございました。 今回のコードは、限定的にしか使えないと思っていまして、 安心して使えるのはBaseの操作をManagerに肩代わりさせるようなパターンぐらいでしょうか。
    9re at 08 Nov 2010 15:40
    いえいえ、こちらこそ。 最近Javaを書いているものですから、考えさせられました!

    Tags

    Embed
/**
 * Copyright asahiufo ( http://wonderfl.net/user/asahiufo )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/x8Ps
 */

package {
    import flash.text.TextFieldAutoSize;
    import flash.text.TextField;
    import flash.display.Sprite;
    
    public class FlashTest extends Sprite implements ICtx1, ICtx2
    // public class FlashTest extends Sprite
    {
        private var _tracer:TextField;
        
        public function show1():void { return _tracer.appendText("show1実行" + "\n"); }
        public function show2():void { return _tracer.appendText("show2実行" + "\n"); }
        
        public function FlashTest()
        {
            _tracer = new TextField();
            _tracer.autoSize = TextFieldAutoSize.LEFT;
            addChild(_tracer);
            
            var manager:Manager = new Manager();
            manager.base = new Sub1();
            manager.init(this);
            manager.base = new Sub2();
            manager.init(this);
            try
            {
                manager.base = new Sub3();
                manager.init(this);
            }
            catch (e:Error)
            {
                _tracer.appendText(e.toString());
            }

        }
    }
}

class Manager
{
    private var _base:Base;
    
    public function get base():Base { return _base; }
    public function set base(value:Base):void { _base = value; }
    
    public function init(context:Object):void
    {
        _base.runInitFunc(context);
    }
}

class Base
{
    public function runInitFunc(context:Object):void
    {
        var initFunc:Function = this["initialize"] as Function;
        if (initFunc == null)
        {
            return;
        }
        initFunc(context);
    }
}

class Sub1 extends Base
{
    public function initialize(context:ICtx1):void
    {
        context.show1();
    }
}
class Sub2 extends Base
{
    public function initialize(context:ICtx2):void
    {
        context.show2();
    }
}
class Sub3 extends Base
{
}
interface ICtx1
{
    function show1():void;
}
interface ICtx2
{
    function show2():void;
}