none
入れ子になったクラスについて RRS feed

  • 質問

  • 下記のように、入れ子となったクラスについての質問です。
    public class Parent
    {
      /* メンバ */
      
      private class Child { }
    }

    【質問1】
    このとき、Childクラスから見たParentクラスは、一般的に何と呼ぶのでしょうか。
    親クラスや基底クラス、スーパクラスだと、継承関係を指すのだと認識していますが。
    同じように、Parentから見たChildは、どのように呼ぶのでしょうか。

    【質問2】
    このようなクラス定義が可能となっている目的は何でしょうか。
    私は勝手に「Parentクラス以外から利用できないクラス」を作るために使っていますが、
    果たしてこの目的のために使うことが適正なのかどうか、知りません。

    【質問3】
    Parentインスタンス内でChildインスタンスを生成したとき、
    ChildインスタンスからParentインスタンスの参照を得る方法はありますか?
    (ChildのメンバにParentを持たせる、というのはナシで・・・)
    Childがpublicになっている場合にはそもそもあり得ないケースなので、
    多分無いだろうなと思いつつ、もしかしたら・・・? とのことで質問させていただきました。

    どなたかご存知の方、お願い致します。

    2011年6月28日 4:53

回答

  • femp さんこんにちは、おのでらです。

    【質問1】

    ⇒ChildクラスはParentクラス「内部クラス」とか「インナークラス」でしょうか

    【質問2】

    ⇒その考えで問題ないと思います。ChildクラスがpublicであればParentは名前空間のような意味合いでもいいかもしれません(あくまでもParentのChildクラスという意味で考える)

    【質問3】

    ⇒自動で参照できる仕組みはありません。Windows Form のListViewItem や TreeViewItem を見てみるとわかりますが別途 Parent の参照プロパティを持つように定義されています。


    おのでら (http://sorceryforce.com/)
    • 回答としてマーク femp 2011年6月28日 5:27
    2011年6月28日 5:16
  • 内部クラス(インナークラス)、外部クラス(アウタークラス)などと呼びます。その他については以下にわかりやすく書かれていますので、一度読まれると良いでしょう。

    C#とJavaのInner Class?-システム開発23
    http://plaza.rakuten.co.jp/u008expert/diary/20060922/

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク femp 2011年6月28日 5:27
    2011年6月28日 5:19
    モデレータ

すべての返信

  • femp さんこんにちは、おのでらです。

    【質問1】

    ⇒ChildクラスはParentクラス「内部クラス」とか「インナークラス」でしょうか

    【質問2】

    ⇒その考えで問題ないと思います。ChildクラスがpublicであればParentは名前空間のような意味合いでもいいかもしれません(あくまでもParentのChildクラスという意味で考える)

    【質問3】

    ⇒自動で参照できる仕組みはありません。Windows Form のListViewItem や TreeViewItem を見てみるとわかりますが別途 Parent の参照プロパティを持つように定義されています。


    おのでら (http://sorceryforce.com/)
    • 回答としてマーク femp 2011年6月28日 5:27
    2011年6月28日 5:16
  • 内部クラス(インナークラス)、外部クラス(アウタークラス)などと呼びます。その他については以下にわかりやすく書かれていますので、一度読まれると良いでしょう。

    C#とJavaのInner Class?-システム開発23
    http://plaza.rakuten.co.jp/u008expert/diary/20060922/

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク femp 2011年6月28日 5:27
    2011年6月28日 5:19
    モデレータ
  • 回答ありがとうございます。

    おかげでもやもやが晴れました。

    2011年6月28日 5:27
  • 【質問1】
    このとき、Childクラスから見たParentクラスは、一般的に何と呼ぶのでしょうか。
    親クラスや基底クラス、スーパクラスだと、継承関係を指すのだと認識していますが。
    同じように、Parentから見たChildは、どのように呼ぶのでしょうか。

    Child から見て Parent だと、英語であれば "outer class" で決まりなんでしょうが、日本語だと「外部クラス」「アウター クラス」だったりしますね。
    MSDN だと "outer type" の訳が「外側の型」になっているので、「外側のクラス」なんでしょうか。

    入れ子にされた型 (C#)
    http://msdn.microsoft.com/ja-jp/library/ms173120(VS.80).aspx

    【質問2】
    このようなクラス定義が可能となっている目的は何でしょうか。
    私は勝手に「Parentクラス以外から利用できないクラス」を作るために使っていますが、
    果たしてこの目的のために使うことが適正なのかどうか、知りません。

    これについては次の記事が参考になると思います。

    内部クラスの使いどころ
    http://blogs.wankuma.com/nagise/archive/2007/08/01/88273.aspx

    ちなみに、「.NET のクラスライブラリ設計」という書籍には、「ネストされた型とその囲い込み型との間の関係が、ネスト型のようなメンバアクセシビリティ上のセマンティクスを持つことが望ましいとき、ネスト型を使用します。」とあります。(96 ページ)

    # このページを見ると、Parent が「囲い込み型」で Child が「ネスト型」になっているなぁ。

    【質問3】
    Parentインスタンス内でChildインスタンスを生成したとき、
    ChildインスタンスからParentインスタンスの参照を得る方法はありますか?
    (ChildのメンバにParentを持たせる、というのはナシで・・・)
    Childがpublicになっている場合にはそもそもあり得ないケースなので、
    多分無いだろうなと思いつつ、もしかしたら・・・? とのことで質問させていただきました。

    これについては、その通りかと。
    2011年6月28日 5:28
  • 【質問2】
    このようなクラス定義が可能となっている目的は何でしょうか。
    私は勝手に「Parentクラス以外から利用できないクラス」を作るために使っていますが、
    果たしてこの目的のために使うことが適正なのかどうか、知りません。

    私は、むしろ逆の理由で、「Child クラスからしか呼び出せないメンバ」を Parent クラス側に作成したい場合に設計として使用することが多いです。つまり、

    public class Outer
    {
      public Outer() { ... }
    
      /* : */
    
      // 外部から呼び出されたくない連携用メソッド
      private void method1() { ... }
    
      /* : */
    
      public class Inner
      {
        private readonly Outer owner;
    
        public Inner(Outer owner) { this.owner = owner; }
        /* : */
    
        public void method2()
        {
           // 内側のクラスからは外側のクラスの private が利用できる
           this.owner.method1();
        }
    
        /* : */
      }
    }
    
    


    こんなかんじですね。internal でもいいんですが、internal より狭い範囲に可視性を与えることができます。

    2011年6月30日 5:35