반응형
package nesting_interface_class;

public class NestingClassA {
	int aField = 5;
	void aMethod1() {};
	
	static int aField2 = 10;
	static void aMethod2() {};
	
    class NestingClassB{
		NestingClassB() {} 	// 생성자
		int field1; // 인스턴스 필드
		// static int field2; // 정적 필드 사용불가(x)
		void method1() { System.out.println("중첩 클래스B");} // 인스턴스 메소드
		// static void method2() {} // 정적 메소드 사용불가(x)
		
		void method2() {
			class NestingClassD { // *로컬 클래스*
				NestingClassD() {} 	// 생성자
				int field1;	// 인스턴스 필드
				// static int field2;	// 정적 필드 사용불가(x)
				void method1() {System.out.println("로컬 클래스");} // 인스턴스 메소드
				// static void method2() {}	// 정적 메소드 사용불가(x)
			}
			NestingClassD  D = new NestingClassD();
			D.field1 =3 ;
			D.method1();
		}
		
		// 멤버 클래스 에서 사용 제한 가능 여부
		void callA () {
			aField = 10; // A 인스턴스 필드
			aMethod1();  // A 인스턴스 메소드
			
			aField2 = 10; // A 정적 필드
			aMethod2(); // A 정적 메소드
			

			NestingClassA.this.aMethod1();  // 바깥 클래스 메소드 참조 (A 인스턴스 메소드)
			NestingClassA.this.aField = 10; // 바깥 클래스 필드 참조 (A 인스턴스 필드)
			this.field1 = 10; // 현재 클래스의 필드 참조 (B 인스턴스 필드)
			this.method1();	// 현재 클래스의 메소드 참조 (B 인스턴스 메소드)
		}
	}
	
	static class NestingClassC{
		NestingClassC() {};  // 생성자
		int field1; // 인스턴스 필드
		static int field2; // 정적 필드
		void method1() {System.out.println("중첩 클래스C");}; // 인스턴스메소드
		static void method2() {System.out.println("static 중첩 클래스C");}; // 정적 메소드
		
		void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2();	// A 정적 메소드
		}
	}
}
package nesting_interface_class;

public class NestingClass {

	public static void main(String[] args) {
		
		NestingClassA A = new NestingClassA();
		NestingClassA.NestingClassB B = A.new NestingClassB();				
		B.field1 = 3; // 인스턴스 필드
		B.method1(); // 인스턴스 메소드
		
		NestingClassA.NestingClassC C = new NestingClassA.NestingClassC();
		C.field1 =3; // 인스턴스 필드
		C.method1(); // 인스턴스 메소드
		NestingClassA.NestingClassC.field2 = 3; // 정적 필드
		NestingClassA.NestingClassC.method2(); // 정적 메소드
	}

}


클래스 내부에 선언한 클래스입니다.
두 클래스의 멤버들을 서로 쉽게 접근할 수 있다는 특징과
클래스를 감춤으로서 코드의 복잡성을 줄일 수 있다는 특징을 가지고 있습니다.

멤버클래스도 하나의 클래스이기 때문에 컴파일하면 바이트 코드파일이 별도로 생성됩니다.

 

NestingClassA A = new NestingClassA();
NestingClassA.NestingClassB B = A.new NestingClassB();				
B.field1 = 3; // 인스턴스 필드
B.method1(); // 인스턴스 메소드

먼저 A객체(바깥클래스)를 생성후 B객체(내부클래스)를 생성해야 합니다.

 

static class NestingClassC{
		NestingClassC() {};  // 생성자
		int field1; // 인스턴스 필드
		static int field2; // 정적 필드
		void method1() {System.out.println("중첩 클래스C");}; // 인스턴스메소드
		static void method2() {System.out.println("static 중첩 클래스C");}; // 정적 메소드
		
		void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2(); // A 정적 메소드
		}

또한 내부 클래스를 static으로 만든 경우에만 static으로 필드나 메소드를 정의할 수 있습니다.

 

  class NestingClassB{
  	...
    void callA () {
        aField = 10; // A 인스턴스 필드
        aMethod1();  // A 인스턴스 메소드

        aField2 = 10; // A 정적 필드
        aMethod2(); // A 정적 메소드


        NestingClassA.this.aMethod1();  // 바깥 클래스 메소드 참조 (A 인스턴스 메소드)
        NestingClassA.this.aField = 10; // 바깥 클래스 필드 참조 (A 인스턴스 필드)
        this.field1 = 10; // 현재 클래스의 필드 참조 (B 인스턴스 필드)
        this.method1();	// 현재 클래스의 메소드 참조 (B 인스턴스 메소드)
	}
}

내부 클래스가 static이 아니라면 바깥 클래스가 정적으로 정의되든 안 되든 접근이 가능합니다.

 

또 다른 접근 방법은 this를 이용해 접근할 수 있습니다. (바깥클래스.this.필드 or 메소드)

현재 클래스의 필드나 메소드도 접근할 수 있습니다. (this.필드 or 메소드)

 

static class NestingClassC{
	....
	void callA () {
			// aField = 10; // A 인스턴스 필드 사용불가(x)
			// aMethod1(); // A 인스턴스 메소드 사용불가(x)
			
			aField2 = 10; // A 정적 필드
			aMethod2();	// A 정적 메소드
	}
}

내부 클래스 static 선언된 경우에는 static으로 선언된 필드 메소드만 접근이 가능합니다.

 

class NestingClassB{
		void method2() {
			class NestingClassD { // *로컬 클래스*
				NestingClassD() {} 	// 생성자
				int field1;	// 인스턴스 필드
				// static int field2;	// 정적 필드 사용불가(x)
				void method1() {System.out.println("로컬 클래스");} // 인스턴스 메소드
				// static void method2() {}	// 정적 메소드 사용불가(x)
			}
			NestingClassD  D = new NestingClassD();
			D.field1 =3 ;
			D.method1();
		}
}

내부 클래스안에 메소드 안에 클래스를 또 만들어서 사용할 수도 있습니다.

이걸 로컬 클래스라고 합니다.

반응형