- 이너클래스(inner class)
- 클래스 내부에 포함
- 종류
- 인스턴스 멤버 이너 클래스
- 정적 멤버 이너 클래스
- 지역 이너 클래스
class A { //아우터 클래스
class B { //인스턴스 멤버 클래스
//...
}
static class C { //정적 멤버 클래스
//...
}
void abc() {
class D { //지역 이너 클래스
//...
}
}
}
1. 인스턴스 멤버 이너 클래스
- 객체 내부에 멤버의 형태로 존재
- 아우터 클래스(outer class)의 모든 접근 지정자의 멤버에 접근 가능
- 소스파일 (.java)이 1개라 하더라도 컴파일을 수행하면 각 클래스별로 바이트 코드(.class)파일 생성
- '아우터 클래스.class'
- ' 아우터 클래스$이너 클래스.class'
- 독립적으로 사용할 수 없고, 반드시 아우터 클래스를 이용해야만 사용 가능
class 아우터 클래스 {
class 이너 클래스 {
//...
}
}
1) 인스턴스 이너 클래스 객체 생성하기
- 이너 클래스의 객체를 생성하기 위해서는 먼저 아우터 클래스의 객체를 생성
- 이후 생성한 아우터 클래스 객체의 참조 변수를 이용해 객체 내부에 있는 이너 클래스의 생성자 호출
아우터 클래스 아우터 클래스 참조 변수 = new 아우터 클래스();
아우터 클래스.이너 클래스 참조 변수 = 아우터 클래스 참조 변수.new 이너 클래스();
class A {
class B {
}
}
A a = new A();
A.B b = a.new B();
- 이너 클래스 객체의 자료형 A.B
- 생성되는 바이트 코드 A$B.class
package InnerClass;
class A {
public int a = 3;
protected int b = 4;
int c = 5;
private int d = 6;
void abc() {
System.out.println("A 클래스 메서드 abc()");
}
//인스턴스 이너 클래스
class B {
void bcd() {
//아우터 클래스의 필드 사용
// 아우터 클래스의 모든 멤버를 접근 지정자와 상관없이 사용가능
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
//아우터 클래스의 메서드 호출
abc();
}
}
}
public class InnerClass {
public static void main(String[] args) {
//아우터 클래스 객체 생성
A a = new A();
//멤버 사용
A.B b = a.new B();
b.bcd();
}
}
2) 아우터 클래스의 객체 참조하기
- 이너 클래스 내부에서 this의 의미는 이너 클래스 자신
- 이너 클래스 내부에서 아우터 클래스의 멤버 참조
-> '아우터 클래스명.this'를 명시적으로 붙여 사용
ex)
- 클래스 B 내부의 메서드에서 a와 같이 참조 변수 없이 멤버 사용 or this.a
-> B 클래스의 필드 a
- 아우터 클래스의 필드 a를 참조하려면
-> A.this.a와 같이 사용
package InnerClass;
class A {
int a = 3;
int b = 4;
void abc() {
System.out.println("A 클래스 메서드");
}
//인스턴스 이너 클래스 정의
class B {
int a = 5;
int b =6;
void abc() {
System.out.println("B 클래스 메서드");
}
void bcd() {
//이너 클래스의 멤버 호출 또는 사용
System.out.println(a);
System.out.println(b);
abc();
//아우터 클래스의 멤버 호출 또는 사용
System.out.println(A.this.a);
System.out.println(A.this.b);
A.this.abc();
}
}
}
public class InnerClass {
public static void main(String[] args) {
//아우터 클래스 객체 생성
A a = new A();
//이너 클래스 객체 생성
A.B b = a.new B();
b.bcd();
}
}
2. 정적 멤버 이너 클래스
- 이너 클래스 앞에 static 키워드가 포함된 이너 클래스
- 아우터 클래스의 정적 멤버에만 접근 가능 (Static 특성)
1) 정적 이너 클래스 객체 생성하기
- 컴파일 이후 '아우터 클래스.class' '아우터 클래스$이너 클래스.class'의 바이트 코드 파일 생성
- 정적 멤버이므로 클래스명으로 바로 접근 가능
- 아우터 클래스의 객체를 생성하지도 않고 바로 사용 가능
아우터 클래스.이너 클래스 이너 클래스 참조 변수 = new 아우터 클래스.이너 클래스();
class A {
static class B{
}
}
A.B b = new A.B();
package InnerClass;
class A {
int a = 3;
static int b = 4;
void method1() {
System.out.println("instance method");
}
static void method2() {
System.out.println("static method");
}
//정적 이너 클래스
static class B {
void bcd() {
//필드 사용
//System.out.println(a); 정적 이너 클래스는 아우터 클래스의 정적 멤버만 사용 가능
System.out.println(b);
//메서드 호출
//method1();
method2();
}
}
}
public class InnerClass {
public static void main(String[] args) {
//정적 이너 클래스의 객체 생성
A.B b = new A.B();
//메서드 호출
b.bcd();
}
}
3. 지역 이너 클래스
- 메서드 내에서 정의되는 클래스
- 지역 변수처럼 정의된 메서드 내부에서만 사용 가능
- 선언 이후 바로 객체를 생성해 사용하며, 메서드가 호출될 때만 메모리에 로딩
- 지역 이너 클래스는 정적 클래스로 지정 불가
- ' 아우터 클래스$ + 숫자 + 지역 이너 클래스.class'
-> 숫자가 포함되는 이유 : 여러 개의 메서드에서 동일한 이름의 지역 이너 클래스를 생성할 수도 있기 때문
1) 이너 클래스 객체 생성하기
- 아우터 클래스의 멤버를 접근 지정자와 상관없이 사용 가능
- 자신이 정의된 메서드의 지역 변수도 클래스 내부에서 사용 가능
- 지역 변수를 사용할 때는 반드시 해당 지역 변수가 final로 선언돼야 함
지역 이너 클래스 지역 이너 클래스 참조 변수 = new 지역 이너 클래스();
class A {
void abc() {
class B { //지역 이너 클래스
}
B b = new B(); //지역 이너 클래스 객체 생성
}
}
package InnerClass;
class A {
int a = 3; //필드
void abc() {
int b = 5; //지역 변수
//지역 이너 클래스
class B{
void bcd() {
System.out.println(a);
System.out.println(b);
a = 5;
//b = 7; 지역 이너 클래스에서 사용하는 지역 변수는 자동 final 선언
}
}
B bb = new B();
bb.bcd();
}
}
public class InnerClass {
public static void main(String[] args) {
//객체 생성 및 메서드 호출
A a = new A();
a.abc();
}
}
- 지역 이너 클래스의 컴파일 이후 생성되는 클래스 파일
package InnerClass;
class A { // A.class
void abc() {
class B {} //A$1B.class
class C {} //A$1C.class
}
void bcd() {
class C {} //A$2C.class
class D {} //A$1D.class
}
}
public class InnerClass {
public static void main(String[] args) {
}
}
'Java' 카테고리의 다른 글
13 - 3 장 이너 인터페이스 (0) | 2023.06.05 |
---|---|
13 - 2 장 익명 이너 클래스 (0) | 2023.06.05 |
12 - 2장 인터페이스 (0) | 2023.06.04 |
12-1장 추상 클래스 (0) | 2023.06.02 |
11-2장 abstract 제어자 (0) | 2023.06.02 |