티스토리 뷰
1. Nested Class(중첩 클래스)에 대한 자바 스펙 문서 정리
[ Nested Class(중첩 클래스)에 대하여 ]
자바에서는 한 클래스 내에서 다른 클래스를 정의할 수 있는데, 이를 nested 클래스라고 한다. nested 클래스는 다시 static 클래스와 non-static 클래스로 나눌 수 있다.
- static: static nested class라고 부름
- non-static: inner class라고 부름
class OuterClass {
// inner class 라고 부름
class InnerClass {
...
}
// static nested class 라고 부름
static class StaticNestedClass {
...
}
}
nested 클래스는 해당 클래스를 둘러싸는 클래스의 멤버이다. 따라서 inner 클래스(non-static nested 클래스)는 해당 클래스를 감싸는 클래스의 멤버들로 접근할 수 있으며, 해당 멤버가 private으로 선언되어 있어도 가능하다. 반면에 static nested 클래스는 감싸는 클래스의 다른 멤버로 접근할 수 없다.
class OuterClass {
private String name;
public OuterClass(String name) {
this.name = name;
}
// inner class 라고 부름
class InnerClass {
public void print() {
System.out.println(name);
}
}
// static nested class 라고 부름
static class StaticNestedClass {
public void print() {
System.out.println(name); // 컴파일 에러 발생
}
}
}
public 또는 package-private으로만 선언될 수 있는 OuterClass와는 달리, nested 클래스는 OuterClass의 멤버로써, public과 package-private 외에도 protected, private으로도 선언될 수 있다.
[ Inner 클래스에 대하여 ]
Inner 클래스는 외부 클래스의 인스턴스와 연관이 있다. Inner 클래스의 인스턴스는 외부 클래스의 인스턴스 내에 존재하기 때문이다. 따라서 Inner 클래스는 다음과 같이 외부 클래스 객체로부터 생성하고 사용할 수 있으며, 외부 클래스 객체의 메서드 및 필드에 직접 접근할 수 있는 것이다.
@Test
void innerClass() {
OuterClass outerObject = new OuterClass("MangKyu");
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
innerObject.print();
}
class OuterClass {
public OuterClass(String name) {
this.name = name;
}
private String name;
// inner class 라고 부름
class InnerClass {
public void print() {
System.out.println(name);
}
}
}
[ Static Nested 클래스 ]
클래스 메서드 및 클래스 변수와 마찬가지로 Static Nested 클래스는 Outer 클래스에 정의된 인스턴스 변수나 메서드를 직접 참조할 수 없으며, 객체 참조를 통해서만 사용할 수 있다. Static Nested 클래스는 사실상 패키징 편의를 위해 다른 최상위 클래스에 중첩된 최상위 클래스인 것이다.
public class StaticClassTest {
@Test
void staticNestedClass() {
StaticNestedClass staticNestedObject = new StaticNestedClass();
staticNestedObject.print();
}
}
class OuterClass {
public OuterClass(String name) {
this.name = name;
}
private String name;
// static nested class 라고 부름
static class StaticNestedClass {
public void print() {
}
}
}
[ Nested Class(중첩 클래스)의 필요성 ]
중첩 클래스를 사용해야 하는 주된 이유는 다음과 같다.
- 한 곳에서만 사용되는 클래스를 논리적으로 그룹화할 수 있다: 어떤 클래스가 다른 클래스 하나에만 유용하다면 해당 클래스에 포함시켜 두 클래스를 함께 유지하는 것이 논리적이다. 그러면 패키지가 더욱 간소화된다.
- 캡슐화가 증가한다: 두 개의 최상위 클래스인 A와 B가 있을 때, B가 A의 private 멤버에 접근해야 한다면 B 클래스를 A 내부에 둠으로써 A의 private 멤버에 접근할 수 있을 뿐만 아니라 B 자체를 외부에서 숨길 수도 있다.
- 더 읽기 쉽고 유지 관리하기 쉬운 코드를 만들 수 있다: 최상위 클래스 안에 작은 클래스를 중첩하면 함께 사용되는 코드들이 더욱 가깝게 배치된다.
참고