클래스가 여러 클래스와 관계를 맺는 경우에는 독립적으로 선언하는 것이 좋으나, 특정 클래스만 관계를 맺을 경우에는 중첩 클래스로 선언하는 것이 유지보수에 도움이 되는 경우가 많다.
클래스 내부에 선언한 클래스
| 선언 위치에 따른 분류 | 선언 위치 | 객체 생성 조건 | |
|---|---|---|---|
| 멤버 클래스 | 인스턴스 멤버 클래스 | class A { |
class B { … }
} | A 객체를 생성해야만 B 객체를 생성할 수 있음 |
| | 정적 멤버 클래스 | class A {
static class B { … }
} | A 객체를 생성하지 않아도 B 객체를 생성할 수 있음 |
| 로컬 클래스 | | clas A {
void method() {
class B { … }
}
} | method가 실행할 때만 B 객체를 생성할 수 있음 |
[public] class A {
[public | private] class B {
}
}
인스턴스 멤버 클래스 B는 주로 A 클래스 내부에서 사용되므로 private 접근 제한을 갖는 것이 일반적이다. B 객체는 인스턴스 필드값, 생성자, 인스턴스 메소드에서 생성할 수 있다.
→ A 객체가 있어야 B 객체도 생성할 수 있기 때문이다.
[public] class A {
[public | private] static class B {
}
}
정적 멤버 클래스는 A 클래스 내부에서 사용되기도 하지만, A 클래스 외부에서 A와 함께 사용되는 경우가 많기 때문에 주로 default 또는 public 접근 제한을 가진다.
B 객체는 A 클래스 내부 어디든 객체를 생성할 수 있다.
[public] class A {
public A() {
class B { }
}
public void method() {
class B { }
}
}
로컬 변수를 로컬 클래스에서 사용할 경우 로컬 변수는 final 특성을 갖게 된다.
→ 값을 읽을 수만 있고 수정할 수 없다. 로컬 클래스 내부에서 값을 변경하지 못하도록 제한하기 때문
중첩 인터페이스는 클래스의 멤버로 선언된 인터페이스를 말한다.
→ 왜 클래스 내부에 선언? 해당 클래스와 긴밀한 관계를 맺는 구현 객체를 만들기 위해서
class A {
[public | private] [static] interface B {
// 상수 필드
// 추상 메소드
// 디폴트 메소드
// 정적 메소드
}
}