본문 바로가기

Java

[JAVA]중첩 클래스의 개념과 멤버, 로컬 클래스

객체 지향 프로그램에서는 클래스들 간에 서로 긴밀한 관계를 맺고 상호작용을 한다. 어떤 클래스는 여러 클래스와 관계를 맺고 어떤 클래스는 특정 클래스와만 관계를 맺는다. 이 때 특정 클래스하고만 관계를 맺는 경우 클래스를 클래스안에 넣어주는 것이 좋다. 왜 좋을까?

  • 두 클래스의 멤버들을 서로 쉽게 접근 가능하다.
  • 외부에 불필요한 클래스를 감추어 코드를 간결하게 한다.

이렇게 클래스안에 클래스가 들어가는 경우를 중첩 클래스라고 한다.

class ClassEx1 {
  class ClassEx2 {//ClassEx2는 중첩 클래스이다.
  }
}

중첩 클래스는 클래스 내부에 선언되는 위치에 따라 두 가지로 분류 된다.

  • 멤버 클래스
    • 클래스의 멤버로서 선언됨
    • 클래스나 객체가 사용 중이라면 언제든지 재 사용 가능
    • 인스턴스 맴버클래스와 정적 멤버 클래스가 있음.(자세한 설명은 뒤에서)
  • 로컬 클래스
    • 메소드 내부에서 선언됨
    • 메소드 실행 시에만 사용되고 메소드 종료시 없어짐

멤버 클래스와 로컬 클래스도 하나의 클래스이기 때문에 컴파일을 하게 되면 바이트 코드 파일인 .class가 생성된다.

//A는 바깥 클래스 B는 멤버 클래스
//멤버 클래스의 바이트 코드파일명
A $ B .class 
//로컬 클래스의 바이트 코드파일명
A $1 B .class

인스턴스 멤버 클래스

인스턴스 멤버 클래스는 static 키워드 없이 선언된 클래스를 의미한다. 인스턴스 멤버 클래스는 인스턴스 필드와 인스턴스 메소드만 선언이 가능하다.

정적 필드와 정적 메소드 같은게 안된다는 것

class A {
  class B {//인스턴스 멤버 클래스
    int field1;
    //static inr field2; (x)
    B() {}
    void method1() {}
  }
}

A클래스 외부에서 B 클래스의 객체를 생성하려면 A객체를 생성한 후 B 객체를 생성해야한다.

A a = new A();
A.B b = a.new B();
b.field1 = 1;
b.method();

정적 멤버 클래스

정적 멤버 클래스는 static 키워드로 선언된 클래스를 의미한다. 정적 멤버 클래스의 경우 인스턴스 멤버 필드와 다르게 모든 종류의 필드와 메소드 선언이 가능하다.

class A {
  static class C {//정적 멤버 클래스
    int field1;
    static int field2; //가능함.
    C() {}
    void method1() {}
  }
}

A클래스 외부에서 C 클래스의 객체를 생성하려면 A객체를 생성하고 C객체를 생성할 필요 없이 바로 C객체를 다음과 같이 생성하면 된다.

A.C c = new A.C();
c.field1 = 1;
A.C.field2 = 2; // 다음과 같이 정적 필드를 사용한다.
c.method();

로컬 클래스

로컬 클래스는 메소드 내에 클래스가 있는 것이다. 로컬 클래스는 접근 제한자와 static을 붙일 수 없다. 왜냐하면 메소드 내부에서만 사용 되는 것이기 때문에 접근을 제한하고 할 게 없기 때문이다. 필드와 메소드도 인스턴스로 사용해야한다.

void method() {
  class D{
    D() {}
    int field1;
    //static int field2; (x)
    //private int field3; (x)
    void method1() {}
  }
  D d =new D();
  d.field1 = 1;
  d.method1();
}

메소드가 실행될 때 메소드 내에서 객체를 생성하고 사용해야 하는 특징 때문에 비동기 처리를 위해 스레드 객체를 만들 때 사용한다.

void method() {
  class DownThread extends Thread { ... }
  DownThread thread = new DownThread();
  thread.start();
}