하나의 클래스 내부에 선언된 또 다른 클래스를 의미하며, 두 클래스가 서로 긴밀한 관계가 있거나 하나의 클래스 또는 메소드에서만 사용되는 클래스일 때 이용되는 기법이다.
class OuterClass {
int field = 10;
int getField() {
return field;
}
class InnerClass {
int getOuterfield() {
return OuterClass.this.getField(); // 숨은 외부 참조가 있기 때문에 가능
}
}
}
public class Main {
public static void main(String[] args) {
// 1. 외부 클래스를 인스턴스화 해주기
OuterClass outer = new OuterClass();
// 2. 외부클래스.내부클래스 형식으로 내부 클래스를 초기화하여 사용할 수도 있다
OuterClass.InnerClass inner = outer.new InnerClass();
inner.getOuterfield();
// 1 + 2
OuterClass.InnerClass inner2 = new OuterClass().new InnerClass();
}
}
class PocketBall {
int size = 100;
static int price = 5000;
// static 내부 클래스
static class PocketMonster {
static String name = "이상해씨";
int level = 10;
// 외부 클래스 인스턴스 멤버 접근
// 방법 : 내부 클래스 생성자에 외부 클래스 객체를 넘겨 접근
public PocketMonster(PocketBall outer) {
System.out.println(outer.size); // 100
}
public static void getPoketMember() {
// 외부 클래스 인스턴스 멤버 접근 불가능
// System.out.println(size);
// 외부 클래스 정적 멤버 접근 가능
System.out.println(price); // 5000
// 내부 클래스 멤버도 정적 멤버만 접근 가능
// System.out.println(level);
System.out.println(name); // 이상해씨
}
}
}
public class Main {
public static void main(String[] args) {
// 정적 내부 클래스의 인스턴스는 외부 클래스를 먼저 생성하지 않아도 된다.
PocketBall.PocketMonster poketmon = new PocketBall.PocketMonster(new PocketBall());
System.out.println(poketmon.level); // 10
System.out.println(PocketBall.PocketMonster.name); // 이상해씨
// 클래스.정적내부클래스.정적메소드()
PocketBall.PocketMonster.getPoketMember();
}
}
class Outer {
private val outerProperty = "Outer Property"
class Inner(private val out: Outer) {
fun accessOuterField(): String {
return out.outerProperty
}
}
}
fun main() {
val inner = Outer.Inner(Outer())
print(inner.accessOuterField()) // Outer Property
}
class Outer {
val outerProperty = "Outer Property"
inner class Inner {
fun getOuterReference(): Outer = this@Outer
// fun accessOuterField(): String = this@Outer.outerProperty
fun accessOuterField(): String = outerProperty
}
}
fun main() {
val outer = Outer()
val inner = outer.Inner()
// Inner 클래스를 통해 외부 클래스의 인스턴스에 접근
println(inner.accessOuterField()) // Outer Property
// Inner 클래스를 통해 Outer 클래스의 참조에 접근
val outerReference = inner.getOuterReference()
println(outerReference.outerProperty) // Outer Property
}