인스턴스 내부 클래스(Instance Inner Class)란?
인스턴스 내부 클래스는 외부 클래스의 인스턴스에 속하는 클래스를 의미합니다. 즉, 인스턴스 내부 클래스는 외부 클래스의 객체를 생성해야만 사용할 수 있는 클래스입니다.
예시 코드
class Outer {
// 인스턴스 변수
private final int number = 10;
// 인스턴스 내부 클래스
class Inner {
void display() {
// 외부 클래스의 인스턴스 변수에 접근
System.out.println("Outer class number: " + number);
}
}
// 인스턴스 메소드
void createInner() {
Inner inner = new Inner(); // 내부 클래스는 외부 클래스 객체에서만 생성 가능
inner.display();
}
}
인스턴스 내부 클래스 특징
1. 외부 클래스의 멤버에 접근할 수 있습니다.
일반적으로 클래스의 인스턴스 변수에 private으로 설정하면 다른 클래스에서는 접근할 수 없습니다. 그러나 인스턴스 내부 클래스는 private으로 접근을 제한하더라도 해당 인스턴스 변수에 접근할 수 있습니다.
class GeneralClass {
private final String message = "hello world";
}
class Test {
public static void main(String[] args) {
GeneralClass generalClass = new GeneralClass();
// 아래 코드는 접근 불가능
// System.out.println(generalClass.message);
}
}
또한 인스턴스 내부 클래스는 외부 클래스의 private 맴버에도 접근할 수 있습니다.
class Outer {
private final int number = 10;
// 인스턴스 내부 클래스
class Inner {
void display() {
// 외부 클래스의 인스턴스 변수에 접근
System.out.println("Outer class number: " + number);
}
}
void createInner() {
Inner inner = new Inner(); // 내부 클래스는 외부 클래스 객체에서만 생성 가능
inner.display();
}
}
2. 외부 클래스에 대한 의존성이 있습니다.
인스턴스 내부 클래스는 외부 클래스의 객체 없이는 사용할 수 없습니다. 외부 클래스의 인스턴스를 생성한 후에야 내부 클래스를 사용할 수 있습니다.
class Outer {
private final int number = 10;
// 인스턴스 내부 클래스
class Inner {
void display() {
// 외부 클래스의 인스턴스 변수에 접근
System.out.println("Outer class number: " + number);
}
}
void createInner() {
Inner inner = new Inner(); // 내부 클래스는 외부 클래스 객체에서만 생성 가능
inner.display();
}
}
class Test {
public static void main(String[] args) {
Outer outer1 = new Outer();
outer1.createInner();
// 외부 클래스 객체에서만 접근 가능
Outer outer2 = new Outer();
Outer.Inner inner = outer2.new Inner(); // 외부 클래스 객체를 통해 접근
inner.display();
}
}
또한, 접근 제어자를 통해 내부 클래스의 접근을 제한할 수 있습니다.
class Outer {
private final int number = 10;
// 인스턴스 내부 클래스 (private 접근 제어자)
private class Inner {
void display() {
// 외부 클래스의 인스턴스 변수에 접근
System.out.println("Outer class number: " + number);
}
}
void createInner() {
Inner inner = new Inner(); // 내부 클래스는 외부 클래스 객체에서만 생성 가능
inner.display();
}
}
class Test {
public static void main(String[] args) {
Outer outer1 = new Outer();
outer1.createInner();
// 컴파일 오류: Inner는 외부에서 접근 불가능
// Outer outer2 = new Outer();
// Outer.Inner inner = outer2.new Inner(); // 오류 발생
// inner.display();
}
}
언제 사용해야 할까요?
1. 긴밀하게 연관되어 있을 때
인스턴스 내부 클래스는 외부 클래스의 인스턴스 변수와 메소드에 접근할 수 있기 때문에, 두 클래스가 긴밀하게 연관되어 있을 때 사용합니다. 예를 들어, 게임 캐릭터와 그 캐릭터만 사용할 수 있는 아이템처럼 강한 관계가 있을 때 유용합니다.
2. 캡슐화와 내부 구현을 숨기고 싶을 때
내부 클래스는 private 접근 제어자를 통해 외부에서 직접 접근을 차단할 수 있습니다. 이렇게 하면 외부 클래스의 내부 구현을 숨기고, 외부 클래스의 메서드를 통해서만 접근할 수 있도록 할 수 있습니다.
언제 사용하면 안될 까요?
1. 연관성이 적을 때: 두 클래스 간에 관계가 약한 경우 인스턴스 내부 클래스를 사용할 필요가 없습니다. 클래스를 독립적으로 설계하고, 객체 간의 의존성을 최소화하는 것이 좋습니다.
2. 복잡한 구조를 만들 때: 내부 클래스에 너무 많은 책임을 주면 코드가 복잡해지고 유지보수가 어려워질 수 있습니다.
3. 성능상의 이유: 인스턴스 내부 클래스는 외부 클래스 객체에 대한 참조를 유지하고 있기 때문에, 가비지 컬렉션에서 외부 클래스 객체가 제거되지 않는 상황이 발생할 수 있습니다. 이로 인해 메모리 누수 등의 문제가 발생할 수 있습니다.
따라서, 내부 클래스가 필요한 경우가 아니라면 외부 클래스로 독립시켜 사용하는 것이 더 효율적입니다.
요약
- 인스턴스 내부 클래스는 외부 클래스의 인스턴스와 연결되어 있으며, 외부 클래스의 private 멤버에도 접근할 수 있습니다.
- 외부 클래스 객체에서만 생성할 수 있기 때문에 외부 클래스에 의존적입니다.
- 두 클래스가 강하게 연관되어 있거나, 캡슐화를 원하는 경우에 사용해야 하며, 성능이나 복잡성에 문제가 될 경우 사용을 피하는 것이 좋습니다.
'Java' 카테고리의 다른 글
[Java] 동등성 (equals(), hashCode()) (0) | 2025.01.05 |
---|---|
[Java] String, StringBuffer, StringBuilder 차이점 (1) | 2025.01.03 |
[Java] for-each 루프 (0) | 2024.12.04 |
[Java] 리스트 인터페이스 구현 (3) | 2024.11.26 |
[Java] 1급 커넥션 (0) | 2024.10.14 |