2 月 04 2007
インスタンス変数のオーバーライド
インスタンス変数のオーバーライドができないのは、 コンストラクタがprivateにできないのと同様に非常にやっかいな問題だと思うんだけど、今日ついに引っかかった。
クラスの初期化(コンストラクタやコンストラクタから呼ばれるメソッドで使う)用の変数として用意したものは、どうあがいても変更できねぇー。
いや、できるんだけど、早すぎるか、遅すぎるかっていう問題にぶちあたる。
継承したクラスのコンストラクタでsuperの前で変数を変更すれば、親クラスのコンストラクタでご丁寧に最初期化され、superのあとでは当然もう使い終わった後なので、全く意味がない。
クラスの設計がAS3的じゃないってことなんだろうけど、なんだかなぁと思う。萎えるよ。
対処法として
・getter/setterを使う ・initPropsとか、変数初期化メソッドを用意してオーバーロード
というのが考えられる。
今回は仕方ないのでinitPropsメソッドみたいなの用意するけど・・用意するけど・・。なんか納得いかない。スマートじゃない。
getter/setterは論外。ソースが無駄に増えるので極力書きたくないよな。そういう意味でrubyはクール。
-- 対処用の書いてみた。 initializeを変数初期化専門とする。 これはこれでいいかも。。
対処法のおソース
/**
* 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で同名なやつらを見ていない。。
うぉーーー、どうすれう゛ぁ? 今はたいしたことないけど、後々クラス設計で響いてくるぞな。
こういうのはどうかな。
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ぐらいにはしているかな。