본문 바로가기

JAVA/혼자공부하는자바

[JAVA] 중첩 클래스

728x90

중첩 클래스란 클래스 내부에 선언된 클래스이다.

 

사용하는 이유는

1. 두 클래스의 멤버들을 서로 쉽게 접근할 수 있다.

2. 외부에 불필요한 관계 클래스를 감춰 복잡성을 줄일 수 있다.

 

class ClassName{
	class NestedClassName{
    }
}

위와 같은 형태로 이루어져 있다.

 

class ClassName{
	Interface NestedInterfaceName{
    }
}

인터페이스도 클래스 내부에 선언할 수 있는데 이를 중첩 인터페이스라고 한다.

 


중첩 클래스

멤버 클래스 : 클래스의 멤버로 선언되어 있는 클래스를 멤버 클래스라고 한다.

 

로컬 클래스 : 클래스의 메소드나 생성자 내부에서 선언되어 있는 클래스를 로컬 클래스라고 한다.

 

멤버클래스는 클래스나 객체가 사용중이라면 언제든지 재사용이 가능하지만 로컬 클래스는 메소드를 실행할 때만 사용되고 메소드가 종료되면 없어진다.

 

선언 위치에 따른 분류 선언 위치 설명
멤버 클래스 인스턴스 멤버 클래스 class A {
    class B { ... }
}
A 객체를 생성해야만 사용할 수 있는
B 클래스
정적 멤버 클래스 class A {
    static class B { ... }
}
A 클래스로 바로 접근할 수 있는
B 클래스
로컬 클래스 class A { 
   void method() {
     class B { ... }
     }
}
method()가 실행할 때만 사용할 수 있는 B 클래스

 

중첩 클래스도 컴파일시 바이트 코드 파일(.class)이 별도로 생성된다.

 

 

A $ B .class

(바깥 클래스 $ 멤버 클래스)

멤버 클래스인 경우 $가 포함되며

 

A $1 B .class

(바깥 클래스 $1 로컬 클래스)

로컬 클래스 경우 $1이 포함된다.

 

 

인스턴스 멤버 클래스

class A {
	/** 인스턴스 멤버 클래스 **/
	class B {
    B() { }					   //생성자
    int field1;				   // 인스턴스 필드
    //static int field2;	   // 정적 필드 (X)
    void method1() {}		   // 인스턴스 메소드
    //static void method2() {} // 정적 메소드 (X)
    }
}

인스턴스 멤버 클래스는static 키워드 없이 중첩 선언된 클래스이며 인스턴스 멤버 클래스는 인스턴스 필드와 메소드만 선언이 가능하며 정적 필드 메소드는 선언할 수 없다.

 

 

 

A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();

A클래스 외부에서 B객체를 생성하기 위해서는 A객체를 생성하고 B객체를 생성해야 한다.

 

 

class A {
	class B { ... }
    
    void methodA() {
    	B b = new B();
        b.field = 3;
        b.method1();
     }
}

A클래스 내부의 생성자 및 인스턴스 메소드에서는 일반 클래스 처럼 B 객체를 생성할 수 있다.

 

보통 A클래스 외부에서 B를 생성할 일은 없으며 대부분 A클래스 내부에서 B객체를 생성해서 사용한다.

 


정적 멤버 클래스

 

정적 멤버 클래스는 static 키워드로 선언된 클래스이다.

정적 멤버 클래스는 모든 종류의 필드와 메소드를 선언할 수 있다.

 

class A {
  /** 정적 멤버 클래스 **/
  static class C {
    C() { }      // 생성자
    int field1;  // 인스턴스 필드
    static int field2; // 정적 필드
    void method1() {}  // 인스턴스 필드
    static void method2() {} // 정적 메소드
    }
}

 

 

A.C c = new A.C();
c.field = 3;   //인스턴스 필드 사용
c.method1();   //인스턴스 메소드 호출

A.C.field2 = 3;  // 정적 필드 사용
A.C.method2();   // 정적 메소드 호출

C객체를 생성하기 위해서는 A객체를 생성할 필요 없이 위와 같이 C객체를 생성하면 된다.

 


로컬 클래스

메소드 내 선언하는 중첩 클래스를 로컬 클래스라고 함.

 

메소드가 호출될 때만 사용할 수 있기 때문에 접근 제한자와 static을 붙일 수 없다.

 

void emthod() {
	/** 로컬 클래스 **/
    class D {
    D() { }  //생성자
    int field1;  //인스턴스 필드
    //static int field2; // 정적 필드(X)
    void method1() { }  // 인스턴스 메소드
    //static void method2() { }  // 정적 메소드(X)
	    }
	D d = new D();
    d.field1 = 3;
    d.method1();
}

 

로컬 클래스는 메소드가 실행될 때 메소드 내에서 객체를 생성하고 새용해야 한다.

주로 비동기 처리를 위해 스레드 객체를 만들 때 사용한다.