ためになるホームページ お問い合わせ




TOP > Java > インナークラス
インナークラス
クラスの中にクラスを定義する。インナークラスはメンバと同じように扱える。

インナークラスの例
class OuterClass{

    //インナークラス
    class InnerClass{

    }
}


インナークラスにアクセスするには、アウタークラスのインスタンスが必要。アウタークラスのメンバからインナークラスにアクセスするには、普通にインナークラスのインスタンスを生成すればよい。

アウタークラス内でインナークラスのインスタンス生成の例
class OuterClass{

    //インナークラスにアクセスするメソッド
    void getInner(){
        InnerClass i = new InnerClass() ;//インナークラスのインスタンス生成
    }

    //インナークラス
    class InnerClass{

    }
}


getInner()メソッドを使用するときには、OuterClassのインスタンスが必要なので、この例は有効。(OuterClassのインスタンスを呼び出さないとアクセスできない為。)

実際にアクセスしてみる例
class OuterClass{

    void getInner(){
        InnerClass i = new InnerClass() ;
        i.getInner() ;
    }

    //インナークラス
    class InnerClass{
        void getInner(){
            System.out.println("Inner Class!") ;
        }
    }
    public static void main(String[] args){
        OuterClass o = new OuterClass() ;
        o.getInner() ;
    }
}


アウタークラスの外のクラスや静的メソッド内からアクセスするには、以下のようにしてインナークラスのインスタンスを生成する必要がある。

アウタークラスの外のクラスや静的メソッド内からアクセスする例
//OuterClass o = new OuterClass ;//アウタークラスのインスタンス生成
//OuterClass.InnerClass i = o.new InnerClass() ;//iがインナークラスを参照する変数
//もしくは、
//OuterClass.InnerClass i = new OuterClass().new InnerClass() ;//iがインナークラスを参照する変数

class OuterClass{
    private int a = 3 ;
    class InnerClass{
        void getInner(){
            System.out.println("Inner Class!") ;
            System.out.println(a) ;
        }
    }
}
class TestMain{
    public static void main(String[] args){
        OuterClass.InnerClass i = new OuterClass().new InnerClass() ;
        i.getInner() ;
    }
}


メソッド内のインナークラス
メソッド内にもクラスを定義できる。この場合、クラス定義直後に、インナークラスのインスタンス生成が必要になる。

アウタークラスの外のクラスからアクセスしてみる例
class Test{
    void getInner(){
        final int a = 2 ;
        class InnerClass{
            void echo(){
                System.out.println(a) ;
                System.out.println("InnerClass") ;
            }
        }
        InnerClass i = new InnerClass() ;
        i.echo() ;
    }
    public static void main(String[] args){
        Test t = new Test() ;
        t.getInner() ;
    }
}


メソッド内のローカル変数は、final宣言された変数しか参照できない。final宣言していないと、コンパイルエラーになる。これは、ローカル変数はメソッドの呼び出しの際にしかローカル変数は存在しないため。

無名インナークラス
あるクラスの無名サブクラスを定義し、そのサブクラスの新しいインスタンスを生成する。

無名インナークラスの例
class Test{
     void getTest(){
         System.out.println("Test") ;
     }
}
class Main{
     public static void main(String[] args){
         Test t = new Test() {
             void getTest(){
                 System.out.println("Sub") ;
             }
         } ;
         t.getTest() ;
    }
}


無名インナークラスは多態性が働くため(オブジェクト型を参考に呼び出すため)、以下のコードは無効。

無効なインナークラスのアクセス例
class Test{
    void getTest(){
        System.out.println("Test") ;
    }
}
class Main{
    public static void main(String[] args){
        Test t = new Test() {//
            void getSub(){
                System.out.println("getSub") ;
            }
            void getTest(){
                System.out.println("getTest") ;
            }
        } ;
        t.getTest() ;
        t.getSub() ;//
   }
}


△離瓮愁奪匹蓮¬橘哨ぅ鵐福璽ラスのメソッドを呼び出している。これは、Testクラスにはない独自のメソッドである。,任寮觚世任蓮Test型の参照であり、実際のインスタンスはTest型なのでコンパイルエラーになる。

インタフェースの実装
インタフェースクラスを実装する無名クラスを作る。インタフェースの無名実装クラスは一つのインタフェースしか実装できない。

インタフェースの実装の例
interface Inter{
    void getInter() ;
}
class Test{
    public static void main(String[] args){
        Inter i = new Inter(){
            public void getInter(){
                System.out.println("インナークラス") ;
            }
        } ;
        i.getInter() ;
    }
}


このコードで作成するのは、Interの無名実装クラスのインスタンス。無名インナークラスは、クラスの継承と実装を同時に行う事はできない。

引数扱いの無名インナークラス
メソッドの引数に無名インナークラスを宣言する。例えば、あるインタフェース型のオブジェクトを引数にとる場合で、まだこのインタフェースの実装クラスがない場合、メソッドの引数内でインナークラス(無名の実装クラス)を作成し、そのインスタンスをメソッドの引数にする。

引数扱いの無名インナークラスの例
interface Inter{
    void getInter() ;
}
interface Inter{
    void getInter() ;
}
class Get{
    void get(Inter i){//
        System.out.println("引数のないインナークラス") ;
    }
}

class Test{
    public static void main(String[] args){
        Get g = new Get() ;
        g.get(new Inter(){//
            public void getInter(){
            }
        } ) ;
    }
}


,離瓮愁奪匹Inter型のオブジェクトを引数に受け取るが、Interクラスはインタフェースなので、インスタンス化できない。そこで、△婆橘召亮汰クラスを作成し、引数としてオブジェクトを渡す。ちなみにここで作成されるクラスは実装クラスなので、全てのメソッドは実装しなくてはいけない。

静的ネストクラス
静的ネストクラスは、「トップレベルネストクラス」「静的インナークラス」とも呼ばれる。静的クラスは、別のクラスのスコープ内にある非インナーのクラス。静的ネストクラスは、アウタークラスとは関係がないため、インナークラスとは言えない。静的ネストクラスはただのアウタークラスの静的メンバーにすぎない。静的ネストクラスは、他の静的メンバーと同様にインスタンスがなくてもアクセスできる。

静的ネストクラスの例
class Test{
    static class Sub{
        static int a = 9 ;
    }

    public static void main(String[] args){
        System.out.println(Sub.a) ;
    }
}


静的ネストクラスのインスタンスを作成するには、以下のようにする。
アウタークラス.静的ネストクラス 識別子 = new アウタークラス.静的ネストクラスのコンストラクタ名 ;

静的ネストクラスのインスタンス生成の例
class Test{
    static class Sub{
        int a = 9 ;
    }

    public static void main(String[] args){
        Test.Sub s = new Test.Sub() ;
        System.out.println(s.a) ;
    }
}







Copyright 2007 ためになるホームページ All Rights Reserved.