オブジェクト向けプログラミング(Java)-内部クラス


内部クラス


クラス内宣言クラスを除いて、普通のクラスとは何も違いません.実際には使用頻度は高くなく、基本原理や特徴の程度を知るだけでよい.
内部クラスInner Classは、クラス内で宣言されるクラスである.クラスに他のクラスを入れるのは、2つのcralsが互いに密接な関係にあるからです.
1つのクラスを別のクラスとして宣言する内部クラスは、2つのクラスのメンバー間で容易にアクセスでき、不要なクラスを非表示にすることができ、コードの複雑さ(カプセル化)を低減します.
class A {
	class InnerA { }
}

種類と特徴


変数による宣言位置の種類と同じです.内部クラスが宣言する場所によって区別できます.
1.インスタンスクラス
外部クラスのメンバー変数宣言位置宣言.外部クラスのインスタンスメンバーのように扱われます.宣言は、主に外部クラスのインスタンスメンバーに関連する操作に使用されます.
2.静的クラス
外部クラスのメンバー変数宣言位置宣言.外部レベルの静的メンバーのように扱われます.宣言は主に外部クラスのstaticメンバー、特にstaticメソッドに使用されます.
3.地域カテゴリ
外部クラスのメソッドまたは初期化ブロックで宣言します.宣言された領域の内部でのみ使用できます.
4.匿名クラス
クラスとオブジェクトを作成する無名の使い捨てクラスを同時に宣言します.
内部クラスは、既存のメンバー変数のようにアクセス制御者を宣言することもできます.
class App {
	private class InstanceInner {			// 인스턴스 클래스
    	// static int cv = 100;				// Error! 인스턴스 클래스는 
        									// static 변수 선언이 안되요
        final static int CONST = 100;		// final static은 상수이므로 허용해요
    }			
    protected static class StaticInner {	// 스태틱 클래스
		int iv = 200;
		static int cv = 200;				// static 클래스만 static 변수 선언 가능
    }
    void method(){
    	class LocalInner {					// 지역 클래스
        	// static int cv = 300;			// Error!
            
	        final static int CONST = 100;		// final static은 상수이므로 허용해요
        }			
    }
}
インスタンス・メンバーは、同じクラスのインスタンス・メンバーと静的メンバーを直接呼び出すことができますが、静的メンバーはインスタンス・メンバーを直接呼び出すことはできません.インスタンス・クラスは、オブジェクトを作成することなく、すぐに外部クラスのインスタンス・メンバーを使用できます.オブジェクト作成なしでは、STATICクラスは外部クラスのインスタンスメンバーを使用できません.
また、ローカルクラスでは、外部クラスのインスタンスメンバーと静的メンバーを同時に使用できます.領域クラスを含むメソッドで定義された領域変数も使用できます.
ただし、final付きの領域変数のみがアクセスできます.これは、メソッドが完了すると、領域変数が消失した場合でも、領域クラスのインスタンスが消失した領域変数を参照するためです.JDK1.8からfinalを省略することができます.これは、finalタイプに指定されていることを意味します.したがって、ゾーンクラスで使用されるゾーン変数を再初期化しようとすると、コンパイルエラーが発生します.

public class InnerEx3 {
    private int outerIv = 0;
    static int outerCv = 0;

    class InstanceInner {
        int iiv = outerIv;      // private 멤버 접근 가능
        int iiv2 = outerCv;
    }

    static class StaticInner {
        // 스태틱 클래스는 외부 클래스의 인스턴스 멤버에 접근 못해요
        // int siv = outerIv;
        static int scv = outerCv;
    }

    void myMethod(){
        int lv = 0;			// 지역 클래스에서 사용하면
        					// 자동으로 뒤에 final이 붙어요
        // lv = 1;			// 초기화를 시도하면 컴파일 에러 발생해요
        final int LV = 0;   // 1.8부터 생략 가능해요
        
        
        class LocalInner {
            int liv = outerIv;
            int liv2 = outerCv;
            // 외부 클래스의 지역 변수는 final이 붙은 변수(상수)만 접근 가능해요
            // 는 1.8부터 안 붙어도 가능해요
            int liv3 = lv;		// 1.8 이전에선 안되요
            					// 1.8부터 final을 자동화해줘요
            int liv4 = LV;
        }
    }
}
クラスの内部クラスを作成または宣言する方法は、次のとおりです.
package ch7;

class Outer {
    class InstanceInner {
        int iv = 100;
    }

    static class StaticInner {
        int iv = 200;
        static int cv = 300;
    }

    void method() {
        class LocalInner {
            int iv = 400;
        }
    }
}

public class InnerEx4 {
    public static void main(String[] args) {
        // 인스턴스 클래스의 인스턴스 생성을 위해선
        // 외부 클래스의 인스턴스를 먼저 생성해야 해요.
        Outer oc = new Outer();
        Outer.InstanceInner ii = oc.new InstanceInner();

        System.out.println("ii.iv : " + ii.iv);
        System.out.println("Outer.StaticInner.cv : " + Outer.StaticInner.cv);

        // 스태틱 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 되요
        Outer.StaticInner si = new Outer.StaticInner();
        System.out.println("si.iv : " + si.iv);
    }
}
参考内部レベルは*.class 외부 클래스명$내부 클래스명.classただし、異なるメソッドで同じ名前の領域変数を使用するように、領域内部クラスは異なるメソッドで同じ名前の内部クラスを持つため、内部クラス名の前に数値が加算されます.
class Outer{
	void method1(){
		class LocalInner {}
    }
    
	void method2(){
		class LocalInner {}
    }
}
この場合、コンパイルは次のクラスファイルを生成します.
Outer.class
Outer$1LocalInner.class
Outer$2LocalInner.class

匿名クラス


匿名レベルAnonymous Classは他の内部レベルとは異なり、名前はありません.クラスの宣言とオブジェクトの作成は同時に行われるため、1回のみ使用でき、1つのオブジェクトの使い捨てクラスしか作成できません.
名前がないため、コンストラクション関数も持つことはできません.親クラスの名前や実装するインタフェースの名前を使用して定義されるため、1つのクラスに継承しながらインタフェースを実装したり、複数のインタフェースを実装したりすることはできません.
匿名クラスを適用する前に
class App {
	Button b = new Button("Start");
    // 익명 클래스를 통해 버튼 기능 설정!
    b.addActionListener(new EventHandler());
}

class EventHandler extends ActionListener {
	public void actionPerformed(ActionEvent e) {
    	System.out.println("ActionEvent occured!");
    }
}
匿名クラスの適用後
class App {
	Button b = new Button("Start");
    // 익명 클래스를 통해 버튼 기능 설정!
    b.addActionListener(new ActionListener() {
    		public void actionPerformed(ActionEvent e) {
            	System.out.println("ActionEvent occured!");
            }
    	}
    );
}