none
親クラスと子クラスとの関係 RRS feed

  • 質問

  • こんにちは、プログラム中困ったことがあったので、質問させていただきました。

    開発環境は「Visual Studio 2005」で、プロジェクトはC#の「windous アプリケーション」です。

     

    以下のソースコードで書いたプログラムが突然停止してしまって、困っています。

     

        public class Koma
        {

            Ou ou = new Ou();
        }

        public class Ou:Koma
        {

        }

     

    実際のソースコードはもうちょと色々書いてあるのですが、たぶん親クラスで子クラスのインスタンスを作成したのが原因だろうと思って厳選しました。

     

    そこで疑問に思ったのですが、設計上の考えかたとして親クラスが子クラスの舵を取るような設計は一般的にまちがっているのでしょうか?

    たとえば今でいうと、親クラスである駒が、子供クラスである王や歩兵などをまとめて管理するような感じです。

    よければ御回答ください。

     

     

     

    2008年12月9日 22:33

回答

  • クラス上の「親子」とデータ管理上の「親子」を混合していますね。
    そのような場合は、デザインパターンで言う「Composite パターン」が適当かと思います。
    Javaの例ですが、とりあえずこちらを参照してみてください。
    http://ja.wikipedia.org/wiki/Composite_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

    必ず有用とは限りませんが、お時間があればデザインパターンに関する情報を一通り調べてみるのも手では?
    2008年12月10日 0:21

すべての返信

  • クラス上の「親子」とデータ管理上の「親子」を混合していますね。
    そのような場合は、デザインパターンで言う「Composite パターン」が適当かと思います。
    Javaの例ですが、とりあえずこちらを参照してみてください。
    http://ja.wikipedia.org/wiki/Composite_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3

    必ず有用とは限りませんが、お時間があればデザインパターンに関する情報を一通り調べてみるのも手では?
    2008年12月10日 0:21
  • お返事ありがとうございます。

     

    なるほど・・・クラス上の親子とデータ上の親子は、またちがうんですね。

    いろいろ調べてみようと思います。ありがとうございました。

     

    2008年12月10日 0:27
  • 外池と申します。「厳選」は、正しいと思いますよ? その上で、よくよく考えてみてください。これだと、Komaのインスタンスをひとつ作ろうとするか、あるいは、Ou:Komaのインスタンスをひとつ作ろうとするかすると、連鎖的に無限にOu:Komaのインスタンスを作り続けようとしてしまいますよね・・・。

     

    例えば、Komaのインスタンスをひとつ作ろうとする。すると、

      Ouのインスタンスを新しく作るわけで、 (ゆくゆくはouにインスタンスの参照を代入するのですが、叶いません。)

        その過程で、派生元のクラスKomaのコンストラクターが呼ばれて、

          Ouのインスタンスを新しくつくるわけで、

            (以下、繰り返し)

     

    とりあえず、この連鎖を生じさせないようにプログラムすることが大事です。

     

    あるクラスのインスタンスが、メンバー変数で同じクラス(派生させたクラスを含む)の別のインスタンスを参照すること自体は全然問題ありません。ものすごく一般的に行われることです。

     

     

     

     

    2008年12月10日 0:38
  •  SE_lain さんからの引用

        public class Koma
        {

            Ou ou = new Ou();
        }

        public class Ou:Koma
        {

        }

     

    基底クラスが派生クラスの型を内部に持つことは、一般的に良い設計とは言えないじゃないかと思います。なぜなら、基底クラスは抽象化を行った結果であり、そこにその抽象化を拡大した派生クラスの厳密な型が入るのであれば、基底クラスで何のために抽象化を行ったのかわからなくなるからです。シンタックス的にどうのというよりも、クラスの継承的な設計としてどうかなと思うのです。簡単な例を出せば、

     

      乗り物 - 飛行機 - B747

               +--- B767

               +--- B777

     

    は、きれいな抽象化だと思いますが、

     

      乗り物 - 飛行機(B747含む) -  B747

               +--------- B767

               +--------- B777

     

    は、きれいに抽象化されているとは一般的に言えないと思いませんか? 

    2008年12月10日 16:05
    モデレータ
  • 外池です。

     

    trapemiyaさんのご指摘、その通りですね。私、ボンヤリとコードを見ていました。Komaの中のメンバー変数の型がOuで宣言されているんでしたね。これは、よろしくないですね。

     

    Komaの中のメンバー変数がKomaで宣言されていて、実行の段階で参照が代入される対象がOuのインスタンスであることもある、というのはOKと思います。

     

    2008年12月11日 1:02
  • >>外池さん

     

    お返事ありがとうございます。

     

    >>例えば、Komaのインスタンス・・・

    あ・・・ほんとですね・・・無限ループしてますね。納得です。

     

     

     

    2008年12月11日 4:25
  • >>trapemiyaさん

    お返事ありがとうございます。

     

    >>基底クラスは抽象化を行・・・

    なるほど・・・確かに抽象化するためにやったのに、基底クラスがそれの実体もつのは変ですよね。ありがとうございます。

     

    2008年12月11日 4:28
  • >>外池さん

    お返事ありがとうございます。

     

    >>実行の段階で参照が代入される対象がOuのインスタンス・・・

    なるほど・・・参照を持つのはOKなんですね。ありがとうございます。

     

    2008年12月11日 4:33