対象に向ける——内部類(4種類)


Javaでは、クラスの内部でクラスを定義することができます。このようなクラスを「内部クラス」と呼びます。この内部クラスがあるクラスを「外部クラス」と呼びます。
内部クラスの位置、修飾子、定義方式によって、内部クラスは、(1)メンバー内部クラスが内部クラスのオブジェクトを作成する具体的な文法形式に分類されます。外部クラス名、内部クラス名変数名=new外部クラス名().new内部クラス名()——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//     Outer
class Outer{
    int m = 0;          //          
    void test1(){       //          
        System.out.println("       ");
    }
    //       Inner
    class Inner{
        int n = 1;
        void show1(){       //1.       ,            
            System.out.println("       m = " + m);
            test1();
        }
        void show2(){
            System.out.println("       ");
        }
    }
    void test2(){           //2.       ,          
        Inner inner = new Inner();
        System.out.println("       n = " + inner.n);
        inner.show2();
    }
}
//     
public class Example{
    public static void main(String[] args){
        Outer outer = new Outer();                          //       
        Outer.Inner inner = outer.new Inner();              //       (              )
        //Outer.Inner inner = new Outer().new Inner();      //              (    :    .         = new     ().new     ())
        inner.show1();      //                     
        outer.test2();      //                   
    }
}
————————————————————————————————————————————————————————(2)局部の内部の種類も“方法の内部の種類”と言って、ある局部の範囲の中の種類を定義して、それは局部の変数と同じに、すべて方法の中で定義したのです。その有効範囲は方法の内部に限られています。————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//     Outer
class Outer{
    int m = 0;
    void test1(){
        System.out.println("       ");
    }
    void test2(){
        //1.       Inner,                 
        class Inner{
            int n = 1;
            void show(){
                System.out.println("     m = " + m);
                test1();
            }
        }
        //2.            ,            
        Inner inner = new Inner();
        System.out.println("       n = " + inner.n);
        inner.show();
    }
}
//     
public class Example{
    public static void main(String[] args){
        Outer outer = new Outer();
        outer.test2();      //                    
    }
}

——————————————————————————————————————————————————————————————————(3)静的な内部の種類は静的な内部の対象の基本的な文法形式を作成します。外部の類名、静的な内部の類名変数名=new外部の類名().静的な内部の類名()
「メンバー内部クラス」に比べて:1.形式的には、静的内部クラスは内部クラスの前にスタティックキーを追加しただけです。2.機能的には、静的な内部クラスでは外部クラスの静的なメンバーにしかアクセスできません。外部のクラスを飛び越えて、直接に内部のクラスを通して静的な内部のメンバーにアクセスできます。————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//     Outer
class Outer {
    static int m = 0;                                           //         m
    static class Inner{
        void show(){
            System.out.println("       m = " + m);      //              
        }
    }
}
//     
public class Example{
    public static void main(String[] args){
        Outer.Inner inner = new Outer.Inner();                  //                
        inner.show();
    }
}
——————————————————————————————————————————————————————————————(4)匿名の内部類(分かりにくい)匿名の内部類を作成する基本的な文法形式:
new    (){
	//         
}
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//       
interface Animal{
    void shout();
}
public class Example{
    public static void main(String[] args){
        String name = "  ";
        //              animalShout()  
        animalShout(new Animal(){
            public void shout(){                        //  shout()  
                System.out.println(name+"  ……");    // Java8  ,     、          final     
            }
        });
    }
    //      animalShout(),        
    public static void animalShout(Animal an){          //      an shout()  
        an.shout();
    }
}
——————————————————————————————————————————————————————————————————————————————————————プログラムの中で局部変数nameにアクセスしましたが、局部変数nameはfinalの修飾を使っていません。プログラムも間違いを報告していません。これはJDK 8からある特性で、局部の内部クラス、匿名の内部クラスでは、非final修飾の【ローカル変数】にアクセスします。JDK 8の前に、ローカル変数の前にfinal修正子を入れなければなりません。そうでなければ、プログラムのコンパイルが間違っています。
初心者にとっては、匿名内部類の書き方は理解しにくいと思われるかもしれませんが、(1)animal Shot()メソッドを呼び出した際に、メソッドのパラメータ位置にnew Animal(){}を記入するという例のオブジェクトを作成し、パラメータとしてアニマルShot()方法にオブジェクトを伝えることができます。new Animal()の後ろには、Animalのサブクラスとして作成されたオブジェクトの例を示す大きな括弧{}があり、このサブクラスは匿名である。具体的なコードは以下の通りです。
animalShout(new Animal(){});
(2)大かっこ{}に匿名のサブクラスの実現コードを作成し、具体的なコードは以下の通りである。
animalShout(new Animal(){
	public void shout(){
		System.out.println(name+"  ……");
	}
})