インスタンス変数のオーバーライド

インスタンス変数のオーバーライドができないのは、 コンストラクタがprivateにできないのと同様に非常にやっかいな問題だと思うんだけど、今日ついに引っかかった。

クラスの初期化(コンストラクタやコンストラクタから呼ばれるメソッドで使う)用の変数として用意したものは、どうあがいても変更できねぇー。

いや、できるんだけど、早すぎるか、遅すぎるかっていう問題にぶちあたる。

継承したクラスのコンストラクタでsuperの前で変数を変更すれば、親クラスのコンストラクタでご丁寧に最初期化され、superのあとでは当然もう使い終わった後なので、全く意味がない。

クラスの設計がAS3的じゃないってことなんだろうけど、なんだかなぁと思う。萎えるよ。

対処法として

・getter/setterを使う ・initPropsとか、変数初期化メソッドを用意してオーバーロード

というのが考えられる。

今回は仕方ないのでinitPropsメソッドみたいなの用意するけど・・用意するけど・・。なんか納得いかない。スマートじゃない。

getter/setterは論外。ソースが無駄に増えるので極力書きたくないよな。そういう意味でrubyはクール。

– 対処用の書いてみた。 initializeを変数初期化専門とする。 これはこれでいいかも。。

対処法のおソース

package sample {
  /**
  * ClassA
  */
  public class ClassA {
    public var initProp:int;
    public function ClassA(){
      initialize();
      trace( initProp );
    }
    protected function initialize():void{
      initProp = 100;
    }
  }
  /**
  * ClassB
  */
  public class ClassB extends ClassA {
    public function ClassB() {
      super();
    }
    override protected function initialize():void{
      initProp = 200;
    }
  }
}

わかったーーーーー!! わかったよぅ。

そのクラスでだけ使いたいインスタンス変数はprivateで宣言すれば良いのだよ、明智君。

つまり ClassAで private var hoge:int = 30;

があったとして

ClassB extends ClassA private var hoge:int = 50;

としても怒られないのだよ。 は?という思う人、うんうん。 AS2じゃあたりまえだからね。 AS3じゃ、継承クラスで同じキーワードを使うと厳しく怒られるのさ。private以外はな。 privateはサブクラスからも参照できないからね。

AS3ではprivateの使い道がよくわからなかった節があるけど、使えるじゃん。 継承したクラスで、同じ名前の変数とかを再定義したい場合はprivateにしちゃえって話だ。継承するごとに毎回記述する必要はあるから、ちょっと慣れないとアレだね。

僕の場合、コンストラクタ内で使いたい変数はほとんどconst扱いだったから

private const hoge:int = 10; ときっちりかけてスッキリだぜ。

–追記

あぁ、ダメだ・・、これは完璧じゃない。 どうしてダメかっていう説明がメンドイくらいダメだ。

今日わかったAS3の特徴 ・privateは継承されない ・継承したメソッドからはprivateなメソッドや変数は使える。 ・継承したメソッドから呼べる変数やメソッドは、親クラスのものなので、サブクラスで新たに定義したprivateで同名なやつらを見ていない。。

うぉーーー、どうすれう゛ぁ? 今はたいしたことないけど、後々クラス設計で響いてくるぞな。

関連記事

  1. 思いつきメモ
  2. ActionScript3とProcessingの勉強2
  3. as3版 CrossDrawer
  4. ActionScript3.0 と Processingの勉強
  5. AS3 ショック
Posted in actionscript3.0, flash, programing at 2月 4th, 2007. Trackback URI: trackback

One Response to “インスタンス変数のオーバーライド”

  1. 3月 22nd, 2007 at 3:42 PM #coinlocker

    こういうのはどうかな。

    public class ClassA { public var initProp:int; protected var initFlag:Boolean = true; public function ClassA(){ if(initFlag) initialize(); trace( initProp ); } } public class ClassB extends ClassA { public function ClassB() { if(initFlag) initialize(); initFlag = false; super(); }

    }

    initPropをprivateにするとsetter/getterの制約があるからね。int型なら疎な結合でも問題ないけど、それ以外なら密に使いたい場合もあるし、私なら大抵protected/internalぐらいにはしているかな。

Leave a Reply