JavaA2Z

KAB-studio > プログラミング > JavaA2Z > 内部クラスとは

内部クラス

日本語 内部種類
英語 inner class
ふりがな ないぶくらす
フリガナ ナイブクラス

解説

クラスクラス
インナークラス」とも言う。
 
特定のクラス外部クラス)内に存在するクラスを「内部クラス」という。
文法的には、外部クラス定義内で定義されたクラスが、内部クラスとなる。
外部クラスの中からは自由に内部クラスを使用できる。外部クラスから、内部クラス変数宣言インスタンスの作成、privateフィールド及びprivateメソッドへのアクセスが可能である。
また同様に、内部クラスは外部クラスを自由に使用できる。
 
内部クラスは、そのインスタンス外部クラスインスタンス内に持つ、という特殊なクラスである。
まず外部クラスインスタンスを作り、次にそのインスタンス参照経由で内部クラスのインスタンスを作ることで、外部クラスインスタンスと結びついた内部クラスのインスタンスを作ることができる。
そうすることで、内部クラスは外部クラスフィールド及びメソッドにアクセスできる。
つまり、外部クラスインスタンス内に内部クラスが含まれているため、内部クラスは外部クラスにアクセスできる、ということである。
この時、内部クラスのインスタンスにとっての「外部クラスインスタンス」を「エンクロージングインスタンス」と呼ぶ。
 
内部クラスは外部クラスフィールド及びメソッドへとアクセスすることができる。内部クラスのインスタンスがあるということは、必ずそのインスタンスを含む外部クラスインスタンスが存在するからである。
ただし、外部クラスインスタンスから内部クラスのインスタンスは見えない。外部クラスインスタンス内に内部クラスのインスタンスがいくつ作られているか知る術はなく、アクセスする方法も存在しない。
そのため、基本的には「あるインスタンスを複数のインスタンスが共有する」という場合に内部クラスを使用するのがいいだろう。
 
内部クラスについて解説している文の多くは、「あるクラスを特定のクラス内でのみ使用する」場合に内部クラスを使用する、とあるが、間違いである。
その目的で使用する場合には、内部クラスでかつprivateクラスとする必要がある。それであれば、目的を達成できる。
しかし、それは内部クラスの本来の目的ではない。内部クラスは「外部クラスインスタンスの中」にインスタンスが作られる、ということにこそ本来の意味がある。
 
ローカルクラス匿名クラスも内部クラスのひとつである。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // まず外部クラスのインスタンスを作ります。
        OuterClass outerClass = new OuterClass();
        // そのインスタンス経由で内部クラスを作ります。
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        // すると、内部クラス経由で外部クラスのフィールドにアクセスできます。
        innerClass.outputOuter();
        // 100

        // また、外部クラスのメソッドなら内部クラスのprivateフィールドに
        // アクセスできます。ただしその際、内部クラスの参照が必要です。
        outerClass.outputInner( innerClass );
        // 200
    }
}

// 外部クラス。
class OuterClass
{
    // privateフィールド。
    private int outerValue = 100;
    
    // 内部クラス。
    public class InnerClass
    {
        // privateフィールド
        private int innerValue = 200;
        
        // メソッド。
        public void outputOuter()
        {
            // ここから、外部クラスのフィールドにアクセスできます。
            System.out.println( outerValue );
        }

        // 内部クラス内にstaticフィールドを作ることはできません。
        // public static int data = 100;
        // コンパイルエラー:
        // フィールド data は static を宣言することはできません。; static フィールドは、static またはトップレベル型においてのみ宣言できます。
    }

    // 外部クラスのメソッドから内部クラスのprivateフィールドに
    // アクセスできます。
    public void outputInner( InnerClass innerClass )
    {
        // ここから、内部クラスのprivateフィールドにアクセスできます。
        System.out.println( innerClass.innerValue );
        // ただし、このようにして引数等で渡してもらう必要があります。
        // なぜなら、外部クラスのインスタンスが作られても、内部クラスの
        // インスタンスが作られるとは限りませんし、内部クラスのインスタンスが
        // 複数作られる場合もあるからです。
        // あくまで「インスタンスで結びついている」という点に注意してください。
    }

    // 内部クラスのインスタンスをstaticメソッド内で作ることはできません。
    public static void staticMethod()
    {
        // 内部クラスのインスタンスをstaticメソッド内で
        // 作ることはできません。
        // new InnerClass();
        // コンパイルエラー:
        // 型 OuterClass のエンクロージング・インスタンスを持つ割り振りを明示的に指定する必要があります。(例 x.new A() で、x が OuterClass のインスタンス)
        
        // Sample.main()の例を見れば分かるとおり、内部クラスは
        // 外部クラスのインスタンスを元にインスタンスを作る必要が
        // あります。そのため、このように内部クラス単独で
        // インスタンスを作ることはできません。
    }

    // 内部クラスのインスタンスは、非staticメソッド内で作ることはできます。
    public void notStaticMethod()
    {
        // 非staticメソッドなら、内部くらすのインスタンスを作ることができます。
        InnerClass innerClass = new InnerClass();

        // これは、外部クラスのインスタンス、つまりこのメソッドの
        // thisが参照するインスタンスの中に、内部クラスのインスタンスが
        // 作られることになります。
        // つまり、これは以下と同じです。
        InnerClass innerClass2 = this.new InnerClass();

        // このように、内部クラスはあくまで「外部クラスのインスタンスの中」
        // にインスタンスが作られる、というわけです。
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // まず外部クラスのインスタンスを作ります。
        OuterClass outerClass = new OuterClass();
        // そのインスタンス経由で内部クラスを作ります。
        OuterClass.InnerClass innerClass = outerClass.new InnerClass();
        // すると、内部クラス経由で外部クラスのフィールドにアクセスできます。
        innerClass.outputOuter();
        // 100

        // また、外部クラスのメソッドなら内部クラスのprivateフィールドに
        // アクセスできます。ただしその際、内部クラスの参照が必要です。
        outerClass.outputInner( innerClass );
        // 200
    }
}

// 外部クラス。
class OuterClass
{
    // privateフィールド。
    private int outerValue = 100;
    
    // 内部クラス。
    public class InnerClass
    {
        // privateフィールド
        private int innerValue = 200;
        
        // メソッド。
        public void outputOuter()
        {
            // ここから、外部クラスのフィールドにアクセスできます。
            System.out.println( outerValue );
        }

        // 内部クラス内にstaticフィールドを作ることはできません。
        // public static int data = 100;
        // コンパイルエラー:
        // フィールド data は static を宣言することはできません。; static フィールドは、static またはトップレベル型においてのみ宣言できます。
    }

    // 外部クラスのメソッドから内部クラスのprivateフィールドに
    // アクセスできます。
    public void outputInner( InnerClass innerClass )
    {
        // ここから、内部クラスのprivateフィールドにアクセスできます。
        System.out.println( innerClass.innerValue );
        // ただし、このようにして引数等で渡してもらう必要があります。
        // なぜなら、外部クラスのインスタンスが作られても、内部クラスの
        // インスタンスが作られるとは限りませんし、内部クラスのインスタンスが
        // 複数作られる場合もあるからです。
        // あくまで「インスタンスで結びついている」という点に注意してください。
    }

    // 内部クラスのインスタンスをstaticメソッド内で作ることはできません。
    public static void staticMethod()
    {
        // 内部クラスのインスタンスをstaticメソッド内で
        // 作ることはできません。
        // new InnerClass();
        // コンパイルエラー:
        // 型 OuterClass のエンクロージング・インスタンスを持つ割り振りを明示的に指定する必要があります。(例 x.new A() で、x が OuterClass のインスタンス)
        
        // Sample.main()の例を見れば分かるとおり、内部クラスは
        // 外部クラスのインスタンスを元にインスタンスを作る必要が
        // あります。そのため、このように内部クラス単独で
        // インスタンスを作ることはできません。
    }

    // 内部クラスのインスタンスは、非staticメソッド内で作ることはできます。
    public void notStaticMethod()
    {
        // 非staticメソッドなら、内部くらすのインスタンスを作ることができます。
        InnerClass innerClass = new InnerClass();

        // これは、外部クラスのインスタンス、つまりこのメソッドの
        // thisが参照するインスタンスの中に、内部クラスのインスタンスが
        // 作られることになります。
        // つまり、これは以下と同じです。
        InnerClass innerClass2 = this.new InnerClass();

        // このように、内部クラスはあくまで「外部クラスのインスタンスの中」
        // にインスタンスが作られる、というわけです。
    }
}

この単語を含むページ

「みだし」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/12/13
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。