[Java]9-1ネストクラス/インタフェースの紹介


ネストされたクラスとは、クラス内で宣言されたクラスです.
ネストされたクラスを使用する利点は、2つのクラスのメンバーに簡単にアクセスでき、不要な関係クラスを隠すことでコードの複雑さを減らすことです.
class Classname{
	class NestedClassName{ //중첩 클래스
	}
}
クラス内で宣言されたインタフェースは、ネストインタフェースとも呼ばれます.
インタフェースをクラス内に宣言するのは、クラスに密接に関連するインプリメンテーションクラスを作成するためです.
class Classname{ 
	interface NestedInterfaceName{ //중첩 인터페이스
    }
}

ネストされたクラス


ネストされたクラスがクラスで宣言された場所に基づいて、メンバークラス(クラスのメンバーとして宣言されたネストされたクラス)とローカルクラス(ジェネレータまたはメソッド内で宣言されたネストされたクラス)に分けます.
クラスまたはオブジェクトが使用されている場合、メンバークラスはいつでも繰り返し使用できますが、ローカルクラスはメソッドの実行時にのみ使用され、メソッドの終了時には消えます.

ネストされたクラスもクラスであり、コンパイル時にバイトコードファイル(.class)が個別に生成されます.
メンバークラスの場合、A$Bです.class(A外部クラスBメンバークラス)、ローカルクラスA$1 B.クラス(A外部クラスBローカルクラス)は、バイトコードファイルを生成する.

インスタンスメンバークラス


インスタンス・メンバー・クラスは、静的キーワードの重複宣言がないクラスです.
インスタンス・メンバー・クラスは、インスタンス・フィールドとメソッドのみを宣言し、静的フィールドとメソッドは宣言できません.


Aクラスの外にBオブジェクトを作成するには、まずAオブジェクトとBオブジェクトを作成する必要があります.(通常、Aクラス以外でBオブジェクトを作成するのはほとんどXであり、ほとんどの場合、Aクラス内でBオブジェクトを作成する)
Aクラス内のジェネレータとインスタンスメソッドでは、通常のクラスを作成するようにBオブジェクトを作成できます.

静的メンバークラス


静的メンバー・クラスは、静的キーで宣言されるクラスです.
静的メンバークラスは、任意のタイプ(インスタンス、静的)のフィールドとメソッドを宣言できます.


Aクラスの外に静的メンバークラスCのオブジェクトを作成するには、Aオブジェクトを作成する必要はありません.Cオブジェクトを次のように作成します.

ローカルクラス


ローカルクラスは、メソッド内で宣言されたネストされたクラスです.
ローカルクラスにはアクセス制限(public、private)、staticは追加できません.ローカルクラスはメソッド内でのみ使用されるため、アクセスを制限する必要はありません.
ローカルクラス内では、インスタンスフィールドとメソッドのみが宣言され、静的フィールドとメソッドは宣言されません.

ローカルクラスは、メソッドの実行時にメソッド内でオブジェクトを作成および使用する必要があります.非同期処理用のスレッドオブジェクトの作成に使用します(12章).
package sec03.exam02;

class A {
	
    //바깥 클래스
	A(){
		System.out.println("A 객체가 생성됨");
	}
	
    //인스턴스 멤버 클래스
	class B{
		
		B(){
			System.out.println("B 객체가 생성됨");
		}
		
		int field1;
		//static int field2;
		void method1() {}
		//static void method(){}
	}
	
    //정적 멤버 클래스
	static class C{
		
		C(){
			System.out.println("C 객체가 생성됨");
		}
		
		int field1;
		static int field2;
		void method1() {}
		static void method2(){}
				
	}
	
	void method() {
		//로컬 클래스
		class D{
			D(){
				System.out.println("D 객체가 생성됨");
			}
			int field1;
			//static int field2;
			void method1() {}
			//static void method2(){}
		}
		
		D d = new D();
		d.field1=3;
		d.method1();
	}
	

}
package sec03.exam02;

public class Main {

	public static void main(String[] args) {
		// TODO 자동 생성된 메소드 스텁
		
		A a = new A();
		
		//인스턴스 멤버 클래스 객체 생성
		
		A.B b=a.new B();
		b.field1=3;
		b.method1();
		
		//정적 멤버 클래스 객체 생성
		A.C c = new A.C();
		c.field1=3;
		c.method1();
		A.C.field2=3;
		A.C.method2();
		
		//로컬 클래스 객체 생성을 위한 메소드 호출
		a.method();

	}

}
Aオブジェクトが作成されました
Bオブジェクトが作成されました
Cオブジェクトが作成されました
Dオブジェクトが作成されました

ネストされたクラスへのアクセス制限


メンバー・クラス内で外部クラスのフィールドとメソッドにアクセスする場合に制限されます.また、ローカルクラスでメソッドのパラメータやローカル変数を使用する場合にも制限されます.

外部フィールドとメソッドでの使用を制限

package sec03.exam02;

public class A {
	
	//인스턴스 필드
	B field1=new B();
	C field2=new C();
	
	//인스턴스 메소드
	void method1() {
		B var1=new B();
		C var2=new C();
	}
	
	//정적 필드 초기화
	//static B field3 = new B(); (X)
	static C field4 = new C();
	
	//정적 메소드
	static void method2() {
		//B var1 = new B(); (X)
		C var2 = new C();
	}
	
	
	//인스턴스 멤버 클래스
	class B{}
	
	//정적 멤버 클래스
	static class C{}
	
}
外部クラスでインスタンスメンバークラスを使用する場合に制限があります.インスタンスメンバークラス(B)は、外部クラスのインスタンスフィールド(フィールド1)の初期値またはインスタンスメソッド(メソッド1)でオブジェクトを作成できますが、静的フィールド(フィールド3)の初期値または静的メソッド(メソッド2)でオブジェクトを作成することはできません.
ただし、静的メンバークラス(C)は、任意のフィールドの初期値または任意のメソッドからオブジェクトを作成できます.

メンバー・クラスの使用を制限

package sec03.exam02;

public class A {
	
	int field1;
	void method1() {}
	
	static int field2;
	static void method2() {}
	
	class B{
		
		void method() {
			field1=10;
			method1();
			
			field2=10;
			method2(); //모든 필드와 메소드에서 접근가능
			}
	}
	
	static class C{
		void method() {
			//field1=10; (X) , 정적 클래스에선 인스턴스 필드와 메소드에 접근X
			//method1(); (X) , 정적 클래스에선 인스턴스 필드와 메소드에 접근X
			
			field2=10;
			method2();
		}
	}

}
メンバー・クラスはインスタンスまたは静的に宣言されるため、メンバー・クラス内で外部クラスのフィールドおよびメソッドにアクセスする場合にも制限されます.
インスタンス・メンバー・クラス(B)では外部クラスのすべてのフィールドおよびメソッドにアクセスできますが、静的メンバー・クラス(C)では外部クラスの静的フィールド(フィールド2)およびメソッド(メソッド2)にのみアクセスでき、インスタンス・メンバーにアクセスできません.

ローカルクラスの使用制限

package sec03.exam02;

public class Outter {
	public void method2(int arg) {
		int localVariable = 1;
		//arg =100; (X)
		//localVariable = 100; (X)
		//자바 8 이후로 final 키워드를 붙이지 않아도 매개변수와 로컬변수에 final 특성을 가지고 있음
		class Inner{
			public void method() {
				int result = arg + localVariable;
			}
		}
	}
}
メソッド内のパラメータまたはローカル変数のローカルクラスでの使用には制限があり、Javaはコンパイル時にローカルクラスで使用されるパラメータまたはローカル変数の値をローカルクラスにコピーします.
パラメータ/ローカル変数の値が変更されると、この値はローカルクラスにコピーされた値とは異なるため、パラメータ/ローカル変数finalの特性が与えられます.(finalキーワードを追加する必要はありません)

ネストされたクラスから外部クラス参照を取得


クラス内では、thisはオブジェクト自体の参照です.ネストされたクラスでこのキーワードを使用すると、外部クラスのオブジェクト参照ではなく、ネストされたクラスのオブジェクト参照として使用できます.
したがって、ネストされたクラスの内部では「this.フィールド、this.メソッド()を呼び出すと、ネストされたクラスのフィールドとメソッドが使用されます.
ネストされたクラスの内部から外部クラスのオブジェクト参照を取得するには、外部クラスの名前を前に付けるだけです.
ex)外部クラス.this.フィールド
外部レベル.this.メソッド();
package sec03.exam02;

public class Outter {
	String field = "Outter-field";
	void method() {
		System.out.println("Outter-method");
	}
	
	class Nested{
		String field = "Nested-field";
		void method() {
			System.out.println("Nested-method");
		}
		void print() {
			System.out.println(this.field);
			this.method(); //중첩 객체 참조
			
			System.out.println(Outter.this.field);
			Outter.this.method(); //바깥 객체 참조
		}
	}
}
package sec03.exam02;

public class OutterExample {

	public static void main(String[] args) {
		// TODO 자동 생성된 메소드 스텁
		
		Outter outter = new Outter();
		Outter.Nested nested = outter.new Nested();
		nested.print();
	}
}
Nested-field
Nested-method
Outter-field
Outter-method

オーバーラップインタフェース


オーバーラップインタフェースとは、クラスメンバーとして宣言されたインタフェースです.
インタフェースをクラス内に宣言するのは、クラスに密接に関連するインプリメンテーションクラスを作成するためです.
ネストされたインタフェースは、インスタンスメンバーインタフェースと静的メンバーインタフェースとすることができる.インスタンス・メンバー・インタフェースは外部クラスのオブジェクトを使用する必要がありますが、静的メンバー・インタフェースは外部クラスのオブジェクトを必要とせず、外部クラスのみでアクセスできます.
主に静的メンバーインタフェースが用いられ,UIプログラミングではイベントの処理によく用いられる.
package sec03.exam02;

public class Button {

	OnClickListener listener; //인터페이스 타입 필드
	
	void setOnClickListener(OnClickListener listener) { //매개 변수의 다형성
		this.listener=listener;
	}
	
	void touch() {
		listener.onClick(); //구현 객체의 onClick() 메소드 호출
	}
	
	static interface OnClickListener{ //중첩 인터페이스
		void onClick();
	}
}
package sec03.exam02;

public class CallListener implements Button.OnClickListener{

	@Override
	public void onClick() {
		System.out.println("전화를 겁니다.");
	}
}
package sec03.exam02;

public class MessageListener implements Button.OnClickListener{

	@Override
	public void onClick() {
		System.out.println("메시지를 보냅니다.");
	}
}
package sec03.exam02;

public class ButtonExample {

	public static void main(String[] args) {
		// TODO 자동 생성된 메소드 스텁
		Button btn = new Button();
		
		btn.setOnClickListener(new CallListener());
		btn.touch();
		
		btn.setOnClickListener(new MessageListener());
		btn.touch();

	}

}
電話します.
メッセージを送信します.
以上は,ボタンをクリックしたときのイベント処理の2つの方法である.
どのインプリメンテーションオブジェクトを作成してButtonオブジェクトに設定するsetOnClickListener()メソッドは、Buttonのtouch()メソッドの実行結果に依存します.
.
.
.
<この部分の問題を解決するにあたって修正すべき点or残念な点>
  • インタフェースのすべての方法には、共通のキーワードが追加されなければなりません.
  • ネストインタフェースを実装する場合、インタフェース名の前に外部クラスを追加します.貼り付けて