위로
아래
중첩 클래스
중첩 클래스 (nested class)
- 클래스 내부에 선언한 클래스
- 두 클래스의 멤버들을 쉽게 사용할 수 있다
- 불필요한 관계 클래스를 감춰서 코드의 복잡성을 줄일 수 있다
외부 클래스 (outer class)
내부 클래스를 포함한 클래스
중첩 클래스 : 멤버 내부 클래스 (member inner class)
public class Outer {
...
class Inner {
}
...
}
- 외부 클래스 안에 선언된 클래스
- 외부 클래스의 변수와 메소드를 사용할 수 있다.(private도 가능)
- 중첩 클래스로 분류된다.
- 컴파일 시 클래스 파일이 '외부클래스$내부클래스.class'로 생성된다.
- 내부 클래스 안에 static 변수 선언 불가.
- 내부 클래스 객체 생성
- 외부 클래스 객체를 먼저 생성한 후에 내부 클래스 객체를 생성할 수 있다
- 외부클래스이름.내부클래스이름 내부객체이름 = 외부객체이름.new 내부클래스이름();
예시
더보기
public class Outer { // 외부 클래스
int a = 10; // 멤버 내부 클래스 접근 가능
private int b = 20; // 멤버 내부 클래스 접근 가능
static int c = 30; // 멤버 내부 클래스 접근 가능
class Inner { // 멤버 내부 클래스
void print() {
System.out.println(a+" "+b+" "+c);
}
}
public static void main(String[]args) {
Outer outer = new Outer(); // 외부 클래스 객체 생성
Outer.Inner inner = outer.new Inner(); // 외부 클래스 객체를 먼저 생성해야 내부 클래스 객체 생성 가능
inner.print(); // 결과 10 20 30
}
}
중첩 클래스 : 지역 내부 클래스 (local inner class)
public class Outer {
...
void outerMethod(){
class Inner { ... }
}
...
}
- 외부 클래스의 메소드 안에서 선언된 클래스
- 메소드 안에서 정의되었기 때문에 로컬 변수처럼 인식
- 메소드가 호출될 때 생성되며 메소드가 종료될 때 삭제됨. (heap 메모리에 할당되기 때문에 사용이 끝나면 가비지 컬렉터에 의해 삭제된다)
- 내부 클래스와 같이 컴파일 시 클래스 파일이 '외부클래스$내부클래스.class'로 생성된다.
예시
더보기
public class Outer {
int a = 10; // 지역 내부 클래스 접근 가능
private int b = 20; // 지역 내부 클래스 접근 가능
static int c = 30; // 지역 내부 클래스 접근 가능
void outerMethod() { // 외부 클래스 메소드
class Inner { //내부 지역 클래스
void print() {
System.out.println(a+" "+b+" "+c);
}
}
Inner inner = new Inner(); // 외부 메소드 안에 내부 클래스 객체 생성
inner.print();
}
public static void main(String[]args) {
Outer outer = new Outer(); // 외부 클래스 객체 생성
outer.outerMethod(); // 외부 클래스 메소드 호출. 결과 10 20 30
}
}
중첩 클래스 : 정적 내부 클래스 (static inner class)
public class Outer {
...
static class Inner { ... }
...
}
- 외부 클래스 안에서 내부 클래스를 정의할 때 static으로 선언
- 내부 클래스 안에는 static 변수를 포함할 수 없지만, 정적 내부 클래스 안에는 static 변수를 포함할 수 있다.
- 외부 클래스 객체를 생성하지 않아도 내부 클래스에 접근이 가능 (static이니까)
- 외부 클래스의 멤버변수와 private로 선언된 변수는 접근이 불가능
예시
더보기
public class Outer { // 외부 클래스 선언
int a = 10; // 정적 내부 클래스 접근 불가
private int b = 20; // 정적 내부 클래스 접근 불가
static int c = 30; // 정적 내부 클래스 접근 가능
static class Inner { // 정적 내부 클래스 선언
static int d = 40; // static 변수 선언 가능
void print() {
//System.out.println(a);
//System.out.println(b);
System.out.println(c); // 외부 클래스 static 변수 접근 가능.
System.out.println(d);
}
static void staticPrint() { // static 메소드 선언 가능
System.out.println(c);
System.out.println(d);
}
}
public static void main(String[]args) {
Outer.Inner inner = new Outer.Inner(); // 외부 클래스 객체 없이 내부 클래스 객체 생성
inner.print(); // 내부 클래스 메소드 접근. 결과 30 40
System.out.println(inner.d); // 내부 클래스 변수 접근. 결과 40
System.out.println(Outer.Inner.d); // static 변수 접근. 결과 40
Outer.Inner.staticPrint(); // static 메소드 접근. 결과 30 40
}
}
중첩 클래스 : 익명 클래스 (anonymous class)
public class Inner {
...
Outer outer = new Outer() {
내용
};
...
}
- 이름이 없는 클래스.
- 선언과 동시에 호출.
- 1회용으로 쓰고 지울 때 사용.
예시
더보기
----------------------인터페이스 Bird.java 파일-----------------------
public interface InterBird {
void move();
void sound();
}
----------------------익명 클래스 AnonymousBoor.java 파일-----------------------
public class AnonymousBoor {
// 원래 interface는 객체 생성이 안 되나, 익명 클래스에서는 표현법만 이렇게 보인다.
// class Anony implements InterBird랑 같은 말.
// InterBird boor = new Anony(); 이렇게 써도 된다.
InterBird boor = new InterBird() { // 중괄호 중요!
@Override
public void move() {
System.out.println("부엉이 날다");
}
@Override
public void sound() {
System.out.println("부엉부엉");
}
};
void method1 () {
boor.move();
boor.sound();
}
}
----------------------메인 클래스 AnonymousDemo.java 파일-----------------------
public class AnnonymousDemo {
public static void main(String[]args) {
AnonymousBoor b = new AnonymousBoor();
b.method1();
}
}
중첩 인터페이스
중첩 인터페이스 (nested interface)
- 클래스 내부에 선언한 인터페이스
- UI 프로그래밍에서 이벤트를 처리할 목적으로 많이 활용된다.
- 외부 클래스와 긴밀한 관계를 맺는 구현 인터페이스를 만들기 위해 사용한다.