Java 기초 또 다시 공부하기 14일차 - 중첩 클래스와 중첩 인터페이스(중첩 클래스와 중첩 인터페이스 개요, 익명 객체)
관련 공부글
Java 기초 또 다시 공부하기 8일차 - 객체 지향 프로그래밍(객체의 특징, 객체 간의 관계, 클래스와
1. 객체의 특징객체(Object): 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중, 고유 속성을 가지고 있어 식별 가능한 것-> 속성과 동작[필드(Field)와 메서드(Method)]으로 구성되어 있음현실
keep-programming-study.tistory.com
2025.06.05 - [자바(JAVA)/미니 프로젝트 & 기초 공부] - Java 기초 또 다시 공부하기 9일차 - 객체 지향 프로그래밍(필드, 생성자, 메서드)
Java 기초 또 다시 공부하기 9일차 - 객체 지향 프로그래밍(필드, 생성자, 메서드)
1. 필드(Field)1) 필드의 개념 및 선언개념: 객체의 고유 데이터, 객체가 가져야 할 부품, 객체의 현재 상태 저장선언: 클래스 중관호 {} 블록 내부에 "타입 필드명( = 초기값);"과 같은 형식으로 선언-
keep-programming-study.tistory.com
2025.06.16 - [자바(JAVA)/미니 프로젝트 & 기초 공부] - Java 기초 또 다시 공부하기 13일차 - 인터페이스, 인터페이스의 타입 변환과 다형성
Java 기초 또 다시 공부하기 13일차 - 인터페이스, 인터페이스의 타입 변환과 다형성
관련 공부글2025.06.04 - [자바(JAVA)/미니 프로젝트 & 기초 공부] - Java 기초 또 다시 공부하기 8일차 - 객체 지향 프로그래밍(객체의 특징, 객체 간의 관계, 클래스와 인스턴스 속성과 동작[필드(Field)
keep-programming-study.tistory.com
1. 중첩 클래스와 중첩 인터페이스 개요
1) 중첩 클래스(nested class)
- 클래스 내부에 선언한 클래스
- 두 클래스의 멤버들에 서로 쉽게 접근 가능, 외부의 불필요한 관계 클래스를 감춰 코드의 복잡성을 줄임
- 중첩 클래스도 하나의 클래스이므로, 컴파일하면 바이트 코드 파일(.class)이 별도 생성됨
-> 바이트 코드 파일 이름은 멤버 클래스의 경우 A클래스$B클래스.class, 로컬 클래스의 경우 A클래스$1B클래스.class - 중첩 클래스의 코드 형태
class ClassName {
// 중첩 클래스
class NestedClassName {
}
}
- 분류
선언 위치에 따른 분류 | 선언 위치 | 설명 | |
멤버 클래스 (클래스의 멤버로서 선언) |
인스턴스 멤버 클래스 | class A { class B { ... } } |
A 객체를 생성해야만 사용할 수 있는 B 클래스 |
정적 멤버 클래스 | class A { static class B { ... } } |
A 클래스로 바로 접근할 수 있는 B 클래스 | |
로컬 클래스 (생성자 또는 메서드 내부에서 선언) |
class A { void method () { class B { ... } } } |
method()가 실행될 때만 사용할 수 있는 B 클래스 |
(1) 인스턴스 멤버 클래스
- static 키워드 없이 중첩 선언된 클래스
- 인스턴스 필드와 인스턴스 메서드만 선언 가능(정적 필드와 정적 메서드 선언 x)
class A {
// 인스턴스 멤버 클래스
class B {
B() {} // 생성자
int field1; // 인스턴스 필드
void method1() {} // 인스턴스 메서드
}
}
(2) 정적 멤버 클래스
- static 키워드로 선언된 클래스
- 모든 종류의 필드와 메서드 선언 가능
class A {
// 정적 멤버 클래스
static class B {
B() {} // 생성자
int field1; // 인스턴스 필드
static int field2; // 정적 필드
void method1() {} // 인스턴스 메서드
static void method2() {} // 정적 메서드
}
}
(3) 로컬 클래스
- 메서드 내에 중첩 클래스 선언
- 메서드 내부에서만 사용되므로 접근 제한이 필요 없음(접근 제한자를 붙이지 않음)
- 인스턴스 필드와 인스턴스 메서드만 선언할 수 있고, 정적 필드와 정적 메서드 선언 불가
void method() {
// 로컬 클래스
class B {
B() {} // 생성자
int field1; // 인스턴스 필드
void method1() {} // 인스턴스 메서드
}
B b = new B();
b.field1 = 3;
b.method1();
}
2) 중첩 인터페이스(nested interface)
- 클래스 내부에 선언한 인터페이스
- 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위함
- 인스턴스 멤버 인터페이스와 정적 멤버 인터페이스 모두 사용 가능
-> 단 인스턴스 멤버 인터페이스는 바깥클래스의 객체가 있어야 사용 가능하며,
정적 멤버 인터페이스는 객체 없이 바깥 클래스만으로 바로 접근 가능 - 중첩 인터페이스의 코드 형태
class ClassName {
// 중첩 인터페이스
interface NestedClassName {
}
}
2. 익명(annoymous) 객체
- 이름이 없는 객체
- 어떤 클래스를 상속하거나 인터페이스를 구현해야 한다는 조건이 있음
- 이 객체의 내부에서는 외부 로컬 변수는 값이 한 번만 할당되고, 이후 변경되지 않아야 함
- 익명 객체 생성 형태(클래스 이름이 없음)
-> 부모 클래스 변수는 이름이 없는 자식 객체를 참조하고, 인터페이스 변수는 이름이 없는 구현 객체 참조
[상속]
부모클래스 변수 = new 부모클래스() { ... };
[구현]
인터페이스 변수 = new 인터페이스() { ... };
1) 익명 자식 객체 생성
- 자식 클래스를 재사용하지 않고 오로지 특정 위치에서만 사용할 경우(재사용성이 낮을 경우),
자식 클래스를 명시적으로 선언하지 않고 익명 자식 객체 생성 - 익명 자식 객체 생성 방법: 하나의 실행문이므로 끝에는 반드시 ;을 붙이기
부모클래스 [필드|변수] = new 부모클래스(매개값, ..) {
// 필드
// 메서드
};
- 익명 자식 객체 사용 예시
// Greeting.java
interface Greeting {
void sayHello();
}
// Main.java
public class Main {
public static void main(String[] args) {
// 익명 자식 객체 생성: Greeting 인터페이스를 즉석에서 구현
Greeting greeting = new Greeting() {
@Override
public void sayHello() {
System.out.println("Hello, world!");
}
};
greeting.sayHello(); // 출력: Hello, world!
}
}
2) 익명 구현 객체 생성
- 구현 클래스를 재사용하지 않고 오로지 특정 위치에서만 사용할 경우(재사용성이 낮을 경우),
구현 클래스를 명시적으로 선언하지 않고 익명 구현 객체를 생성 - 익명 구현 객체 생성 방법: 하나의 실행문이므로 끝에는 반드시 ;을 붙이기
인터페이스 [필드|변수] = new 인터페이스() {
// 인터페이스에 선언된 추상 메서드의 실체 메서드 선언
// 필드
// 메서드
};
- 익명 구현 객체 사용 예시
// Calculator.java
interface Calculator {
int add(int a, int b);
}
// CalculatorMain.java
public class CalculatorMain {
public static void main(String[] args) {
// 익명 구현 객체 생성: Calculator 인터페이스를 구현한 무명 클래스의 인스턴스
Calculator calc = new Calculator() {
@Override
public int add(int a, int b) {
return a + b;
}
};
System.out.println("3 + 5 = " + calc.add(3, 5)); // 출력: 3 + 5 = 8
}
}