자바에서 클래스 내부에 또 다른 클래스를 정의하는 것을 내부 클래스(inner class)라고 하며, 이를 감싸는 클래스를 외부 클래스(outer class)라고 합니다. 내부 클래스는 클래스의 다섯 번째 구성 요소(속성, 메서드, 생성자, 코드 블록, 내부 클래스)로, 외부 클래스의 private 멤버에 직접 접근할 수 있다는 특징이 있습니다. 이 구조는 클래스 간의 포함 관계를 명확히 표현할 수 있습니다.
내부 클래스 기본 문법
class Outer { // 외부 클래스
class Inner { // 내부 클래스
}
}
// 다른 외부 클래스
class Other {
}
구체적인 예제 코드:
public class InnerClassExample {
public static void main(String[] args) {
}
}
class Outer {
private int number = 100;
public Outer(int number) {
this.number = number;
}
public void display() {
System.out.println("display()");
}
{
System.out.println("초기화 블록");
}
class Inner {
// 외부 클래스 Outer 내부에 정의된 내부 클래스
}
}
내부 클래스의 분류
내부 클래스는 정의 위치에 따라 다음과 같이 나뉩니다:
- 지역 내부 클래스(local inner class): 메서드나 코드 블록 내부에 정의되며, 클래스 이름이 있습니다.
- 익명 내부 클래스(anonymous inner class): 메서드나 코드 블록 내부에 정의되지만 클래스 이름이 없습니다. (매우 중요)
- 멤버 내부 클래스(member inner class): 외부 클래스의 멤버 위치에 정의되며, static 키워드가 없습니다.
- 정적 내부 클래스(static inner class): 외부 클래스의 멤버 위치에 정의되며, static 키워드로 선언됩니다.
지역 내부 클래스 사용법
지역 내부 클래스는 외부 클래스의 메서드나 코드 블록 안에 정의되며, 이름을 가집니다. 주요 특징은 다음과 같습니다:
- 외부 클래스의 private 멤버를 포함한 모든 멤버에 직접 접근할 수 있습니다.
- 접근 제한자(public, private, protected)를 붙일 수 없습니다. 지역 변수와 동일한 특성을 가지기 때문입니다. 단, final은 사용 가능합니다(지역 변수도 final을 사용할 수 있음).
- 유효 범위(scope)는 정의된 메서드 또는 코드 블록 내부로 제한됩니다.
- 외부 클래스 내에서 지역 내부 클래스의 멤버에 접근하려면 객체를 생성한 후 접근해야 하며, 이 작업은 반드시 유효 범위 내에서 이루어져야 합니다.
- 외부의 다른 클래스에서는 지역 내부 클래스에 접근할 수 없습니다(지역 변수와 동일한 특성).
- 외부 클래스와 지역 내부 클래스의 멤버 이름이 충돌할 경우, 기본적으로 가까운 범위(지역 내부 클래스)의 멤버가 우선순위를 가집니다. 외부 클래스의 멤버에 접근하려면
외부클래스명.this.멤버형식을 사용합니다.
지역 내부 클래스 예제:
public class LocalInnerClassDemo {
public static void main(String[] args) {
Sample outer = new Sample();
outer.execute();
System.out.println("main에서의 outer 객체 해시코드: " + outer);
}
}
class Sample {
private int value = 100;
private void helper() {
System.out.println("Sample의 helper() 메서드");
}
public void execute() {
// 지역 내부 클래스 (final로 선언 가능)
final class Internal {
private int value = 800;
public void show() {
// 외부 클래스의 private 멤버에 직접 접근
// 이름 충돌 시 외부 클래스 멤버 접근: Sample.this.value
System.out.println("Internal.value=" + value + ", Sample.value=" + Sample.this.value);
System.out.println("Sample.this 해시코드: " + Sample.this);
helper();
}
}
// 외부 클래스 메서드 내에서 지역 내부 클래스 객체 생성 및 사용
Internal internal = new Internal();
internal.show();
}
}
실행 결과는 지역 내부 클래스의 show() 메서드가 외부 클래스의 private 멤버인 value와 helper() 메서드에 접근할 수 있음을 보여줍니다. 또한 Sample.this.value를 통해 외부 클래스의 value 값에 접근하는 방식을 확인할 수 있습니다.