Java & Kotlin
[Java 기능] 중첩 클래스 (1)
Sue
2022. 2. 13. 15:33
내부 클래스(Inner class)
- 클래스 내부에 선언한 클래스로 이 클래스를 감싸고 있는 외부 클래스(outer class)와 밀접한 관련이 있는 경우 많음
- 다른 외부 클래스에서 사용할 일이 거의 없는 경우에 내부 클래스로 선언해서 사용
- 중첩 클래스라고도 함
- 외부 클래스(outer class)의 private 변수 사용 가능
- 종류 : 인스턴스 내부 클래스, 정적(static) 내부 클래스, 지역(local) 내부 클래스, 익명 내부 클래스
- 익명 내부 클래스가 가장 많이 사용됨
인스턴스 내부 클래스
- 내부적으로 사용할 클래스를 선언 (private으로 선언하는 것을 권장)
- 외부 클래스가 생성된 후 생성됨
- private이 아닌 내부 클래스는 다른 외부 클래스에서 생성할 수 있음
OutClass outClass = new OutClass();
OutClass.InClass inClass = outClass.new InClass(); // 다른 외부 클래스에서 내부 클래스 생성
InnerTest.java
- 인스턴스 내부 클래스에서는 static 변수를 사용할 수 없음
- 인스턴스 내부 클래스는 외부 클래스가 생성된 후 생성됨
- static 변수는 외부 클래스의 생성과 상관없이 사용하는 변수
- static 변수가 생성되는 시점에 인스턴스 내부 클래스가 존재하지 않을 수 있음
package ch01;
class OutClass{ // 외부 클래스
private int num = 10;
private static int sNum = 20;
private InClass inClass;
public OutClass() { // 외부 클래스 생성자에서 내부 클래스 생성
inClass = new InClass();
}
private class InClass{ // 내부 클래스
int iNum = 100;
// static int sNum = 200; 오류
void inTest() {
System.out.println("OutClass num = " + num + "(외부 클래스의 인스턴스 변수)");
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 static 변수)");
System.out.println("InClass iNum = " + iNum + "(내부 클래스의 인스턴스 변수)");
}
}
public void usingClass() {
inClass.inTest();
}
}
public class InnerTest {
public static void main(String[] args) {
OutClass outClass = new OutClass();
outClass.usingClass();
}
}
수행 결과
OutClass num = 10(외부 클래스의 인스턴스 변수)
OutClass sNum = 20(외부 클래스의 static 변수)
InClass iNum = 100(내부 클래스의 인스턴스 변수)
정적 내부 클래스
- 외부 클래스의 생성과 무관하게 사용 가능
- 정적 변수와 정적 메서드 사용 가능
InStaticClass
- 정적 내부 클래스의 일반 메서드에서는 외부 클래스의 인스턴스 변수를 사용할 수 없음
- 정적 내부 클래스는 외부 클래스의 생성과 상관없이 사용 가능
- 외부 인스턴스 변수는 외부 클래스가 생성된 후에 사용할 수 있으므로 변수가 생성되지 않았을 때 메서드가 호출될 수 있음
- 정적 메서드에서는 정적 변수만 사용 가능
static class InStaticClass {
int iNum = 100;
static int sInNum = 200;
void inTest() {
// System.out.println("OutClass num = " + num + "(외부 클래스의 인스턴스 변수)"); 오류
System.out.println("InClass iNum = " + iNum + "(내부 클래스의 인스턴스 변수)");
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 static 변수)");
System.out.println("OutClass sInNum = " + sInNum + "(내부 클래스의 static 변수)");
}
static void sTest() {
// System.out.println("InClass iNum = " + iNum + "(내부 클래스의 인스턴스 변수)"); 오류
System.out.println("OutClass sNum = " + sNum + "(외부 클래스의 static 변수)");
System.out.println("OutClass sInNum = " + sInNum + "(내부 클래스의 static 변수)");
}
}
InnerTest
public class InnerTest {
public static void main(String[] args) {
OutClass.InStaticClass sInClass = new OutClass.InStaticClass();
sInClass.inTest(); // static 클래스의 일반 메서드 호출
System.out.println();
OutClass.InStaticClass.sTest(); // static 클래스의 static 메서드 호출
}
}
수행 결과
InClass iNum = 100(내부 클래스의 인스턴스 변수)
OutClass sNum = 20(외부 클래스의 static 변수)
OutClass sInNum = 200(내부 클래스의 static 변수)
OutClass sNum = 20(외부 클래스의 static 변수)
OutClass sInNum = 200(내부 클래스의 static 변수)