[Kotlin in Action] 15. 코틀린 중첩 클래스
- Coding/Kotlin
- 2022. 5. 23.
반응형
728x90
반응형
중첩클래스
자바처럼 코틀린에서도 클래스 안에 다른 클래스를 선언할 수 있다. 클래스 안에 다른 클래스를 선언하면 도우미 클래스를 캡슐화하거나 코드 정의를 그 코드를 사용하는 곳에 둘때 유용하다.
자바와의 차이점
코틀린의 중첩 클래스는 명시적으로 요청하지않는 한 바깥쪽 클래스 인스턴스에 대한 접근 권한이 없다는 점이다.
JAVA
ButtonJava.java
public class ButtonJava implements View {
@NotNull
@Override
public State getCurrentState() {
return new ButtonState();
}
@Override
public void restoreState(@NotNull State state) {
}
/**
* 중첩 클래스
*/
public class ButtonState implements State {
}
}
State 인터페이스를 구현한 ButtonState 클래스를 정의해서 ButtonJava에 대한 구체적인 정보를 저장한다.
여기서 ButtonState 직렬화 시도시, NotSerializableException 이 발생한다.
직렬화하려는 변수는 ButtonState 타입의 state 인스턴스인데, 왜 ButtonJava 를 직렬화할 수 없다는 예외가 발생할까?
자바에서 다른 클래스 안에 정의한 클래스는 자동으로 내부 클래스(inner class)가 된다.
이 예제의 ButtonState 클래스는 바깥쪽 ButtonJava에 대한 참조를 묵시적으로 포함한다.
그 참조로 인해 ButtonState 를 직렬화할 수 없다.
ButtonJava을 직렬화할 수 없으므로 버튼에 대한 참조가 ButtonState의 직렬화를 방해한다.
이 문제를 해결하기 위해서는 ButtonState 를 static 클래스로 선언해야한다.
자바에서 중첩클래스를 static으로 선언하면 그 클래스를 둘러싼 바깥쪽 클래스에 대한 묵시적인 참조가 사라진다.
public static class ButtonState implements State {}
Kotlin
코틀린 중첩 클래스에 아무런 변경자가 붙지 않으면 자바 static 중첩 클래스와 같다.
class Button : View {
/**
코틀린 중첩 클래스에 아무런 변경자가 붙지 않으면 자바 static 중첩 클래스와 같다.
이를 내부 클래스로 변경해서 바깥 클래스에 대한 참조를 포함하게 만들고 싶다면, inner 변경자를 붙여야한다.
*/
class ButtonState : State {
}
override fun getCurrentState(): State {
TODO("Not yet implemented")
}
override fun restoreState(state: State) {
TODO("Not yet implemented")
}
}
이를 내부 클래스로 변경해서 바깥 클래스에 대한 참조를 포함하게 만들고 싶다면, inner 변경자를 붙여야한다.
class Button : View {
inner class ButtonState : State {
}
...
}
자바와 코틀린의 중첩 클래스와 내부 클래스의 관계
클래스 B 안에 정의된 클래스 A | 자바에서는 | 코틀린에서는 |
중첩 클래스 (바깥쪽 클래스에 대한 참조를 저장하지 않음) | static class A | class A |
내부 클래스 (바깥쪽 클래스에 대한 참조를 저장함) | class A | inner class A |
코틀린에서 내부 클래스(inner) -> 바깥쪽 클래스(outer) 참조에 접근하기
this@Outer을 사용한다.
class Outer {
inner class Inner {
// 내부 클래스 Inner 안에서 바깥쪽 클래스 Outer 의 참조에 접근하려면 this@Outer 라고 써야한다.
fun getOuterReference(): Outer = this@Outer
}
}
반응형
'Coding > Kotlin' 카테고리의 다른 글
[Kotlin in Action] 17. 클래스의 생성자와 초기화 블록, 주 생성자와 부 생성자 (0) | 2022.05.24 |
---|---|
[Kotlin in Action] 16. 봉인된 클래스: 클래스 계층 정의시 클래스 확장 제한 (sealed 변경자) (0) | 2022.05.23 |
[Kotlin in Action] 14. 코틀린의 가시성 변경자 (open, abstract, internal) (0) | 2022.05.22 |
[Kotlin in Action] 13. 코틀린 인터페이스 구현 (0) | 2022.05.21 |
[Kotlin in Action] 12. 로컬함수 확장 (코드 리팩토링, 로컬함수, 중첩함수) (0) | 2022.05.20 |