1. 내부 클래스(Inner Class)
1.1 내부 클래스의 목적과 사용
내부 클래스는 다른 클래스 안에 정의된 클래스로, 외부 클래스의 모든 멤버(비공개 멤버 포함)에 접근할 수 있습니다. 이를 통해 논리적으로 밀접한 클래스 간의 캡슐화를 강화할 수 있습니다.
내부 클래스의 주요 장점은 다음과 같습니다:
- 더 나은 캡슐화 제공.
- 다중 상속 효과 구현.
- 이벤트 리스너 등의 복잡한 구조 단순화.
1.2 내부 클래스와 외부 클래스의 접근 규칙
- 내부 클래스는 외부 클래스의 모든 멤버에 접근 가능(비공개 멤버도 포함).
- 외부 클래스는 내부 클래스의 멤버에 직접 접근 불가능하며, 반드시 내부 클래스 객체를 통해 접근해야 함.
- 내부 클래스는 private, protected, 기본(default), public으로 선언 가능.
예제 코드: University 클래스와 Professor 내부 클래스
class University {
String name;
public class Professor {
String professorName;
int age;
public Professor(String universityName, String profName, int newAge) {
// University 클래스의 name 속성 설정
University.this.name = universityName;
// Professor 클래스의 professorName 속성 설정
this.professorName = profName;
// Professor 클래스의 age 속성 설정
this.age = newAge;
}
public void displayInfo() {
System.out.println("대학 이름: " + University.this.name);
System.out.println("교수 이름: " + this.professorName);
System.out.println("나이: " + this.age);
}
}
public void showProfessorInfo() {
Professor prof = new Professor("스타대학교", "김교수", 45);
prof.displayInfo();
}
}
public class InnerClassExample {
public static void main(String[] args) {
System.out.println("--외부 클래스를 통해 내부 클래스 접근--");
University uni = new University();
uni.showProfessorInfo();
System.out.println("--직접 내부 클래스 접근--");
University.Professor prof = uni.new Professor("스타대학교", "박교수", 40);
prof.displayInfo();
}
}
출력 결과:
--외부 클래스를 통해 내부 클래스 접근--
대학 이름: 스타대학교
교수 이름: 김교수
나이: 45
--직접 내부 클래스 접근--
대학 이름: 스타대학교
교수 이름: 박교수
나이: 40
2. 익명 내부 클래스(Anonymous Inner Class)
2.1 익명 내부 클래스 개요
익명 내부 클래스는 이름이 없는 내부 클래스로, 인터페이스나 추상 클래스를 빠르게 구현하는 데 유용합니다. GUI 프로그래밍에서 이벤트 리스너 등을 간단히 구현하기 위해 자주 사용됩니다.
특징:
- 클래스 이름이 없음.
new키워드를 사용해 부모 클래스 생성자 또는 인터페이스 호출.- 하나의 객체만 생성 가능.
- 코드 구조 단순화에 기여.
2.2 익명 내부 클래스 생성 방법
인터페이스 이름이나 부모 클래스 이름 뒤에 new 키워드를 사용하여 이름 없는 클래스를 만들고 즉시 인스턴스화합니다.
예제 코드: 인터페이스를 이용한 익명 내부 클래스 구현
interface Operation {
int performOperation(int x, int y);
}
public class AnonymousExample {
public static Operation createOperation(char operator) {
if (operator == '*') {
return new Operation() {
@Override
public int performOperation(int x, int y) {
return x * y;
}
};
} else {
return new Operation() {
@Override
public int performOperation(int x, int y) {
return x / y;
}
};
}
}
public static void main(String[] args) {
int num1 = 20, num2 = 4;
Operation multiply = createOperation('*');
System.out.println(num1 + "*" + num2 + "=" + multiply.performOperation(num1, num2)); // 출력: 20*4=80
Operation divide = createOperation('/');
System.out.println(num1 + "/" + num2 + "=" + divide.performOperation(num1, num2)); // 출력: 20/4=5
}
}
출력 결과:
20*4=80
20/4=5
3. 요약
| 유형 | 특징 | 사용 시나리오 |
|---|---|---|
| 내부 클래스 | 이름 존재, 재사용 가능, 외부 클래스 접근 용이 | 여러 객체 필요 시, 강력한 캡슐화 필요 |
| 익명 내부 클래스 | 이름 없음, 한번만 사용, 문법 간결 | 인터페이스/추상 클래스 일회성 호출 시 |