河野真治 @ 琉球大学情報工学です。

In article <1173446801.647540.113770@64g2000cwx.googlegroups.com>, "pegacorn" <subscriber.jp@gmail.com> writes
> > 共通の初期化ルーチンはメソッドとして用意して、それぞれのコンストラクタから
> > 呼び出す、ということはよくやってます。
> 私も時々やってました。
> でも、それってこの件の典型的なはまりパターンではないでしょうか?

だめだめな、C++ を例に出して、

    典型的なはまりパターン

というのは、やめて欲しいなぁ〜

In article <1173408799.067953.89530@30g2000cwc.googlegroups.com>, "pegacorn" <su
bscriber.jp@gmail.com> writes
> ◇C++等の場合
>   メソッドがサブクラスでオーバーライドされていても、サブクラスの
>   メソッドではなく自クラスのメソッドが呼び出される。
>   class SuperClass
>   {
>       SuperClass(const std::string &x):
>           x_(x)
>       {
>           method();
>       }
>   class SubClass: public SuperClass
>       SubClass(const std::string &y):
>           SuperClass(y),
>           y_(y + "def")
>       {
              method();   <--- これが必要
>       }

この場合は SubClass 側で、SubClass.method() を明示的に呼ぶ
必要があります。C++ のようなコンパイル時に親子関係を解決す
る場合は、method()がoverride されていると知っているのは、
SubClass だけだから。

この書き方だと、SubClass.method() が呼ばれる前には、既に
SuperClass.method()が呼ばれているということなので、注意が
必要です。

> ◇Ruby,Java等の場合
>   メソッドがサブクラスでオーバーライドされている場合、サブクラスの
>   メソッドが呼び出されるが、サブクラスでのコンストラクトが完了して
>   いない可能性がある。
>   class SuperClass
>     def initialize(x)
>       @x = x
>       method()
>     end
>   class SubClass < SuperClass
>     def initialize(y)
>       super(y)
>       @y = y + 'def'
              method();   <--- これが必要
>     end

こっちの場合は、SuperClass.initialize 中の method() は、SubClass
のmethod を呼び出すので、SuperClass のmethod() で初期化した
いならば、SubClass 側で super method() を明示的に呼ぶ必要が
あると思います。スクリプト言語、インタプリタでは、そうなる
ことが多い。多重継承だと、super が一つに決らないので、困る
ことが多いね。「Effective C++」でも、そのあたりの記述があります。

いずれにせよ、SubClass のコンストラクタに対する、SubClass 用の
初期化メソッドは、SubClass のコンストラクタから明示的に呼ぶ、
ということなんじゃないかな。呼ばれ方の差はあるにしても。

このあたり、実験的に決めることが多いです。

---
Shinji KONO @ Information Engineering, University of the Ryukyus
河野真治 @ 琉球大学工学部情報工学科