티스토리 뷰
주의 사항!
- 이 글은 제가 직접 공부하는 중에 작성되고 있습니다.
- 따라서 제가 이해하는 그대로의 내용이 포함됩니다.
- 따라서 이 글은 사실과는 다른 내용이 포함될 수 있습니다.
중첩 클래스는 클래스 내부에 선언되는 위치에 따라서 두 가지로 분류됩니다. 클래스의 멤버로서 선언되는 중첩 클래스를 '멤버 클래스'라고 하고, 메서드 내부에서 선언되는 중첩 클래스를 '로컬 클래스'라고 합니다. 멤버 클래스는 클래스나 객체가 사용 중이라면 언제든지 재사용이 가능하지만, 로컬 클래스는 메서드 실행 시에만 사용되고, 메서드가 실행 종료되면 없어집니다.
인스턴스 멤버 클래스
인스턴스 멤버 클래스는 static 키워드 없이 선언된 클래스를 말합니다. 인스턴스 멤버 클래스는 인스턴스 필드와 메서드만 선언이 가능하고 정적 필드와 메서드는 선언할 수 없습니다.
class A
{
//인스턴스 멤버 클래스
class B {
int field1;
//static int field2; 정적 필드 불가
B() { ... }
void method1() { ... }
//static void method2() { ... } 정적 메서드 불가
}
}
A 클래스 외부에서 인스턴스 멤버 클래스 B의 객체를 생성하려면 먼저 A 객체를 생성하고 B 객체를 생성해야 합니다.
A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();
정적 멤버 클래스
정적 멤버 클래스는 static 키워드로 선언된 클래스를 말합니다. 정적 멤버 클래스는 모든 종류의 필드와 메서드를 선언할 수 있습니다.
class A
{
//정적 멤버 클래스
static class C {
int field1;
static int field2; //정적 필드도 가능
C() { ... }
void method1() { ... }
static void method2() { ... } //정적 메서드도 가능
}
}
A 클래스 외부에서 정적 멤버 클래스 C의 객체를 생성하기 위해서는 A 객체를 생성할 필요 없이 다음과 같이 C 객체를 생성할 수 있습니다.
A.C.field2 = 3; //정적 필드 사용
A.C.method2(); //정적 메서드 호출
A.C c = new A.C();
c.field1 = 3;
c.method1();
(앞선 인스턴스 멤버 클래스에서부터 궁금증이 하나 생겼을지 모르겠습니다. 저는 인스턴스 멤버 클래스에는 왜 정적 멤버를 선언할 수 없는지, 정적 멤버 클래스는 왜 인스턴스 멤버와 정적 멤버 모두 선언할 수 있는지 이유가 궁금했습니다. 나름 혼자 생각해 본 결과는 이렇습니다.
정적 멤버 클래스든 인스턴스 멤버 클래스든 이들은 클래스이기 전에 다른 클래스의 멤버입니다. 어떤 클래스의 정적 멤버는 그 클래스의 인스턴스가 생성되지 않아도 사용할 수 있어야 합니다. 반면 인스턴스 멤버는 그 클래스의 인스턴스가 생성되어야만 사용할 수 있습니다.
클래스 A에 클래스 B가 멤버로 선언되었다고 가정해 보겠습니다. 만약 클래스 B에 정적 멤버가 단 하나라도 있으면 우리는 이 멤버를 클래스 B의 인스턴스 생성 없이도 사용할 수 있어야 합니다. 그런데 앞서 말했다시피 클래스 B는 클래스 A의 멤버로서 존재합니다. 만약 클래스 B가 인스턴스 멤버로서 존재한다면 우리는 클래스 A의 인스턴스를 생성해야만 클래스 B의 정적 멤버를 사용할 수 있을 것입니다. 물론 클래스 B의 인스턴스는 생성하지 않아도 되지만 그래도 이 정적 멤버를 사용하기 위해 클래스 A의 인스턴스를 생성해야 할 수밖에 없다는 점에서 정적 멤버의 매력이 반감되는 것 같습니다. 그래서 정적 멤버를 단 하나라도 가지는 클래스 B는 클래스 A의 정적 멤버로서 선언하여, 클래스 A의 인스턴스 생성 없이도 이 멤버를 사용할 수 있게 합니다.)
로컬 클래스
중첩 클래스는 메서드 내에서도 선언할 수 있습니다. 이것을 로컬(local) 클래스라고 합니다. 로컬 클래스는 접근 제한자 및 static을 붙일 수 없습니다. 로컬 클래스는 메서드 내부에서만 사용되므로 접근을 제한할 필요가 없기 때문입니다. 로컬 클래스 내부에는 인스턴스 필드와 메서드만 선언이 가능하고 정적 필드와 메서드는 선언할 수 없습니다.
(로컬 클래스에 선언된 정적 멤버는 애초에 정적 멤버답게 사용할 방법도 없을 것 같습니다.)
void method()
{
//로컬 클래스
class D
{
int field1;
//static int field2; 정적 필드 불가
D() { ... }
void method1() { ... }
//static void method2() { ... } 정적 메서드 불가
}
D d = new D();
d.field1 = 3;
d.method1();
}
로컬 클래스는 메서드가 실행될 때 메서드 내에서 객체를 생성하고 사용해야 합니다. 주로 다음과 같이 비동기 처리를 위해 스레드 객체를 만들 때 사용합니다.
void method()
{
class DownloadThread extends Thread { ... }
DownloadThread thread = new DownloadThread();
thread.start();
}
'공부 일지 > JAVA 공부 일지' 카테고리의 다른 글
자바, 중첩 인터페이스 (0) | 2021.04.13 |
---|---|
자바, 중첩 클래스의 접근 제한 (0) | 2021.04.11 |
자바, 중첩 클래스와 중첩 인터페이스란? (0) | 2021.04.11 |
자바, 디폴트 메서드와 인터페이스 확장 (0) | 2021.04.11 |
자바, 인터페이스 상속 (0) | 2021.04.11 |