중첩 클래스(nested class) : 다른 클래스 내부에 선언된 클래스.
중첩 클래스의 종류 4가지 :
정적 멤버 클래스
정적 멤버 클래스는 바깥 클래스의 인스턴스와 독립적으로 존재할 수 있는 클래스다. 즉, 바깥 클래스의 인스턴스 없이도 생성하고 사용할 수 있다. 정적 멤버 클래스는 바깥 클래스의 정적 멤버에만 접근할 수 있으며, 바깥 클래스의 인스턴스 멤버에는 접근할 수 없다.
비정적 멤버 클래스
비정적 멤버 클래스는 바깥 클래스의 인스턴스와 연관되어 있는 클래스다. 이러한 클래스의 객체는 바깥 클래스의 객체와 연결되어 있으며, 바깥 클래스의 인스턴스 멤버와 메서드에 접근할 수 있다. 비정적 내부 클래스는 바깥 클래스의 인스턴스를 통해서만 생성할 수 있다. 정적 클래스와 의 구문적 차이는 단지 static이 붙어 있고 없고의 차이뿐이지만, 의미상 차이는 꽤 크다.
지역 클래스 (Local Class)
메서드 내부에 선언된 클래스로, 선언된 메서드 내에서만 사용할 수 있다.
익명 클래스 (Anonymous Class)
이름이 없는 클래스로, 주로 단일 인스턴스 생성에 사용된다.
public class OuterClass {
private static int staticVar = 100;
private int instanceVar = 200;
// 정적 멤버 클래스
static class StaticMemberClass {
void display() {
System.out.println(staticVar); // 정적 변수에 접근 가능
// System.out.println(instanceVar); // 컴파일 에러: 인스턴스 변수에 접근 불가
}
}
// 비정적 멤버 클래스
class NonStaticMemberClass {
void display() {
System.out.println(staticVar); // 정적 변수에 접근 가능
System.out.println(instanceVar); // 인스턴스 변수에 접근 가능
}
}
// 메서드 내에서 지역 클래스 사용
void methodWithLocalClass() {
// 지역 클래스 정의
class LocalClass {
void display() {
System.out.println("Inside Local Class. staticVar: " + staticVar + ", instanceVar: " + instanceVar);
}
}
// 지역 클래스 인스턴스 생성 및 사용
LocalClass localInstance = new LocalClass();
localInstance.display();
}
// 메서드 내에서 익명 클래스 사용
void methodWithAnonymousClass() {
// 익명 클래스를 통한 Runnable 인터페이스 구현
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("Inside Anonymous Class. staticVar: " + staticVar);
// instanceVar 접근 가능 (익명 클래스는 비정적 컨텍스트 내에 정의되었기 때문)
System.out.println("instanceVar: " + instanceVar);
}
};
// 익명 클래스 인스턴스 사용
new Thread(runnable).start();
}
public static void main(String[] args) {
OuterClass outerInstance = new OuterClass();
// 정적 멤버 클래스 인스턴스 생성 및 사용
OuterClass.StaticMemberClass staticInstance = new OuterClass.StaticMemberClass();
staticInstance.display();
// 비정적 멤버 클래스 인스턴스 생성 및 사용
OuterClass.NonStaticMemberClass nonStaticInstance = outerInstance.new NonStaticMemberClass();
nonStaticInstance.display();
// 지역 클래스 사용
outerInstance.methodWithLocalClass();
// 익명 클래스 사용
outerInstance.methodWithAnonymousClass();
}
}
결론 : 중첩 클래스에는 네 가지가 있으며, 각각의 쓰임이 다르다.
메서드 밖에서도 사용해야하거나 메서드 안에 정의하기엔 너무 길다면 멤버 클래스로 만든다.
멤버 클래스의 인스턴스 각각이 바깥 인스턴스를 참조한다면 비정적으로, 그렇지 않으면 정적으로 만들자.
중첩 클래스가 한 메서드 안에서만 쓰이면서 그 지점이 단 한곳이고 해당 타입으로 쓰기에 적합한 클래스나 인터페이스가 이미 있다면 익명 클래스로 만들고, 그렇지 않으면 지역 클래스로 만들자.
'이펙티브 자바' 카테고리의 다른 글
[이펙티브 자바] 아이템 26. 로 타입은 사용하지 말라 (0) | 2024.03.27 |
---|---|
[이펙티브 자바] 아이템 25. 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2024.03.25 |
[이펙티브 자바] 아이템 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (2) | 2024.03.22 |
[이펙티브 자바] 아이템 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2024.03.22 |
[이펙티브 자바] 아이템 21. 인터페이스는 구현하는 쪽을 생각해 설계하라 (0) | 2024.03.22 |