1. 중첩 클래스(Nested Class)
클래스 안에 또 다른 클래스를 선언하는 것을 중첩 클래스라고 한다.
중첩 클래스는 타입 이름이 '바깥 클래스.중첩 클래스'로 만들어진다. 생성자 이름도 마찬가지이다.
바깥 클래스와 중첩 클래스의 인스턴스는 서로 어떠한 프로퍼티나 멤버 함수도 공유하지 않는 완전히 별개의 클래스이다. 단순히 식별자만 바깥 클래스에 속해있는 것이다.
class Outher { // 바깥 클래스
class Nested { // 중첩 클래스
fun hello() = println("중첩된 클래스")
}
}
fun main() {
val instance: Outher.Nested = Outher.Nested()
}
다음과 같은 코드는 오류를 일으킨다.
class Outer2 {
private val property: Int = 16
class Nested2 {
fun hello() = println(property) // Unresolved reference: property (알수 없는 참조: property)
}
}
Outer의 인스턴스와 Outer.Nested의 인스턴스를 그림으로 나타내면 다음과 같다.
Outer의 인스턴스와 Outer.Nested의 인스턴스는 서로 어떠한 프로퍼티나 멤버 함수도 공유하지 않는 완전히 별개의 클래스이다.
2. 내부 클래스(Inner Class)
중첩 클래스가 단순히 식별자만 바깥 클래스에 속해있는 것이었다면, 내부 클래스는 인스턴스가 바깥 클래스의 인스턴스에 완전히 소속되는 것이다.
내부 클래스를 선언할 때는 클래스 선언문 앞에 inner 키워드를 붙인다.
class Outer(private val value: Int) {
fun print() {
println(this.value)
}
// Inner 내부 클래스 선언
inner class Inner(private val innerValue: Int) {
fun print() {
this@Outer.print() // Outer의 print
println(this.innerValue + this@Outer.value)
}
}
}
fun main() {
val instance: Outer = Outer(610)
val innerInstance: Outer.Inner = instance.Inner(40)
innerInstance.print()
// 결과
// 610
// 650
}
main 함수의 영역에서 메모리 상황을 표현하면 다음과 같다.
1) Outer의 인스턴스를 생성
2) Outer.Inner 인스턴스 생성
내부 클래스의 인스턴스를 생성하려면 클래스 이름.생성자()가 아닌 참조 변수.생성자()를 해야 한다.
내부 클래스는 바깥 클래스의 인스턴스로부터만 생성할 수 있기 때문이다.
내부 클래스의 인스턴스는 자신이 속해있는 바깥 클래스의 인스턴스를 가리키는 참조 변수를 내부적으로 가지고 있다.
this@Outer의 정체가 위의 내용에 해당하는 것이다.
내부 클래스는 this@Outer 키워드를 이용하여 자신이 속한 바깥 클래스의 인스턴스에 접근할 수 있다.
이런 특성 때문에 내부 클래스의 인스턴스는 반드시 바깥 클래스의 인스턴스.생성자()꼴로 생성해야 한다.
'TIL > Kotlin' 카테고리의 다른 글
[TIL/Kotlin] 코틀린 고급문법_함수 리터럴과 람다식, 익명 함수, it 식별자 (0) | 2023.05.24 |
---|---|
[TIL/Kotlin] 코틀린 고급문법_데이터 클래스와 객체 분해하기 (0) | 2023.05.21 |
[TIL/Kotlin] 코틀린 고급문법_추상 클래스, 인터페이스, 다이아몬드문제(상속구현문제) (0) | 2023.05.17 |
[TIL/Kotlin] 코틀린 고급문법_Nullable 리시버, 동반자 객체의 확장 함수, 확장 함수의 리시버 타입이 상속 관계에 있을 때 참조 변수를 따른다 (0) | 2023.05.17 |
[TIL/Kotlin] 코틀린 고급문법_inline 함수, const, lateinit (0) | 2023.05.17 |