
* 개념 복습과 학습 정도를 파악하고자 포스팅합니다
내부 클래스(Inner Class)
1. 내부 클래스?
클래스 안에 정의된 클래스.
두 클래스가 긴밀하게 연관될 때 하나를 다른 하나의 내부에 정의해서 논리적으로 묶습니다.
class Outer { // 외부 클래스
class Inner { // 내부 클래스
// ...
}
}
내부 클래스를 쓰는 이유는 세 가지가 있어요.
- 캡슐화 강화: 외부에 노출할 필요 없는 클래스를 숨길 수 있습니다.
- 코드 구조화: 관련된 클래스를 논리적으로 묶어 가독성을 높여요.
- 외부 멤버 접근: 내부 클래스는 외부 클래스의 private 멤버에서 자유롭게 접근할 수 있습니다.
내부 클래스는 선언 위치와 static 여부에 따라 4가지로 나누어져요!
| 종류 | 선언 위치 | static | 특징 |
| 인스턴스 내부 클래스 | 클래스 멤버 위치 | X | 가장 일반적 |
| 정적 내부 클래스 | 클래스 멤버 위치 | O | 외부 인스턴스 불필요 |
| 지역 클래스 | 메서드 안 | X | 잘 사용하지 않음 |
| 익명 클래스 | 메서드 안 | X | 이름 없음, 1회용 |
2. 인스턴스 내부 클래스
외부 클래스의 멤버 위치에 선언하는 가장 일반적인 내부 클래스.
외부 클래스의 모든 멤버(private 포함)에 접근할 수 있습니다.
public class Car {
private String model;
private int speed;
public Car(String model) {
this.model = model;
this.speed = 0;
}
// 인스턴스 내부 클래스
class Engine {
private int rpm;
Engine(int rpm) {
this.rpm = rpm;
}
void start() {
// 외부 클래스의 private 필드에 직접 접근 가능
System.out.println(model + " 엔진 시동 — rpm: " + rpm);
speed = 100; // 외부 클래스 필드 수정도 가능
}
void showCarInfo() {
// 외부 클래스 이름.this 로 외부 인스턴스 명시적 참조
System.out.println("차량 모델: " + Car.this.model);
}
}
public void drive() {
Engine engine = new Engine(3000);
engine.start();
}
}
// 사용법
Car car = new Car("소나타");
// 방법 1 — 외부 클래스 메서드를 통해 사용 (일반적)
car.drive(); // 소나타 엔진 시동 — rpm: 3000
// 방법 2 — 외부에서 직접 생성
Car.Engine engine = car.new Engine(5000);
engine.start(); // 소나타 엔진 시동 — rpm: 5000
핵심 포인트
- 인스턴스 내부 클래스 객체를 만들려면 외부 클래스 객체가 먼저 있어야 해요.
- 외부에서 직접 생성할 때는 외부객체.new 내부클래스() 문법을 써요.
- 내부 클래스 안에서 외부 클래스 인스턴스를 참조할 때는 외부클래스.this를 써요.
3. 정적 내부 클래스(Static Nested Class)
static 키워드를 붙인 내부 클래스입니다.
외부 클래스의 인스턴스 없이도 사용할 수 있어요. 단, 외부 클래스의 인스턴스 멤버에는 접근할 수 없고 static 멤버에만 접근할 수 있죠.
public class MathUtil {
private static final double PI = 3.14159;
// 정적 내부 클래스
static class Circle {
private double radius;
Circle(double radius) {
this.radius = radius;
}
double area() {
return PI * radius * radius; // 외부 클래스의 static 필드 접근 가능
}
double circumference() {
return 2 * PI * radius;
}
}
static class Rectangle {
private double width, height;
Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
double area() {
return width * height;
}
}
}
// 외부 클래스 인스턴스 없이 바로 생성 가능
MathUtil.Circle circle = new MathUtil.Circle(5.0);
System.out.println("넓이: " + circle.area()); // 넓이: 78.53975
System.out.println("둘레: " + circle.circumference()); // 둘레: 31.4159
MathUtil.Rectangle rect = new MathUtil.Rectangle(4.0, 6.0);
System.out.println("넓이: " + rect.area()); // 넓이: 24.0
4. 지역 클래스(Local Class)
메서드 안에 선언하는 클래스.
잘 사용하지 않았습니다. 저도 이런게 있구나 정도로만 공부했어요 ㅎ
public class Printer {
void printMessage(String message) {
// 메서드 안에 클래스 선언
class Formatter {
String format(String text) {
return "[" + text.toUpperCase() + "]";
}
}
Formatter formatter = new Formatter();
System.out.println(formatter.format(message));
}
}
Printer printer = new Printer();
printer.printMessage("hello"); // [HELLO]
5. 익명 클래스(Anonymous Class)
이름 없이 선언과 동시에 객체를 생성하는 클래스.
주로 인터페이스나 추상 클래스를 일회성으로 구현할 때 사용합니다.
람다 표현식으로 대체되는 경우가 많지만, 아직도 종종 볼 수 있는 것 같습니다.
// 인터페이스 정의
interface Greeting {
void greet(String name);
}
// 방법 1 — 일반적인 구현 클래스
class KoreanGreeting implements Greeting {
@Override
public void greet(String name) {
System.out.println("안녕하세요, " + name + "님!");
}
}
Greeting g = new KoreanGreeting();
g.greet("홍길동");
// 방법 2 — 익명 클래스 (이름 없이 바로 구현)
Greeting g = new Greeting() {
@Override
public void greet(String name) {
System.out.println("안녕하세요, " + name + "님!");
}
};
g.greet("홍길동"); // 안녕하세요, 홍길동님!
new Greeting() {...} 에서 Greeting은 인터페이스임에도 new를 쓸 수 있습니다.
이 때 { } 안에 구현 코드를 바로 작성할 수 있어요.
6. 익명 클래스 → 람다 표현식
Java 8 부터는 함수형 인터페이스(추상 메서드가 1개인 인터페이스)를 구현할 때 익명 클래스 대신 람다 표현식으로 간결하게 쓸 수 있습니다.
// 함수형 인터페이스
interface Calculator {
int calc(int a, int b);
}
// 익명 클래스 방식
Calculator add = new Calculator() {
@Override
public int calc(int a, int b) {
return a + b;
}
};
// 람다 표현식 방식 — 동일한 결과, 훨씬 간결
Calculator add = (a, b) -> a + b;
System.out.println(add.calc(3, 5)); // 8'Language > Java' 카테고리의 다른 글
| [Java] 예외 처리 (Exception Handling) (0) | 2026.04.23 |
|---|---|
| [Java] String 파헤치기 (0) | 2026.04.23 |
| [Java] 배열에 대해서 (0) | 2026.04.22 |
| [Java] 추상 클래스 & 인터페이스 완전히 정리해버리기 (0) | 2026.04.22 |
| [Java] 상속 완전히 정리해버리기 (0) | 2026.04.22 |