일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- boj
- android
- Rxjava
- 백준
- relay
- Kotlin
- Compose
- 코루틴
- textfield
- Gradle
- MyVoca
- androidStudio
- Coroutines
- architecture
- activity
- Coroutine
- MiTweet
- pandas
- 프로그래머스
- livedata
- 코드포스
- AWS
- TEST
- GitHub
- Codeforces
- 쿠링
- Python
- ProGuard
- Hilt
- 암호학
- Today
- Total
이동식 저장소
[Kotlin] Nested Class, Inner Class 본문
Kotlin에서도 클래스 안에 다른 클래스를 정의할 수 있다. 특정 외부 클래스에 종속된 클래스를 외부로부터 숨기고자 할 때 유용하다. 그러나 Kotlin의 내부 클래스는 기본적으로 외부 클래스의 멤버에 접근할 수 없다. 예시를 하나 들어 보겠다.
``View``를 상속하여 커스텀 뷰를 만들려 한다. 이때 ``View``를 직렬화(serialize) 가능하게 만든다고 생각해 보자. 뷰 자체를 직렬화하기는 쉽지 않지만, 대신 뷰가 가지고 있는 데이터를 직렬화하면 된다. 뷰의 데이터를 담는 일반적인 객체를 정의하기 위해 ``Serializable``을 구현하는 ``State`` 인터페이스를 정의하자.
interface State: Serializable
interface View {
fun getState(): State
fun restoreState(state: State) {}
}
이제 나만의 `Button` 클래스를 작성할 수 있다. 먼저 자바 코드를 보자.
public class Button implements View {
@Override
public State getState() {
return new ButtonState();
}
@Override
public void restoreState(State state) { /*...*/ }
public class ButtonState implements State { /*...*/ }
}
그런데 이 코드는 잘못되었다. 실제로 이 코드를 실행하면 ``NotSerializableException``이 발생한다. 아니 분명히 ``ButtonState``를 구현했는데? 왜지?
자바에서는 클래스 안에 정의한 클래스는 기본적으로 ``inner class``이기 때문이다. 위에서 정의한 ``ButtonState``는 ``Button`` 클래스의 변수와 함수에 접근할 수 있다. ``ButtonState`` 그 자체는 직렬화 가능하지만, 직렬화 불가능한 ``Button``을 참조하고 있기 때문에 결과적으로 ``ButtonState``는 직렬화할 수 없다. 만약 ``ButtonState``가 ``Button`` 밖에 정의됐더라면 문제가 없었을 것이다.
``ButtonState``를 ``static class``로 정의하면 이 문제를 해결할 수 있다. ``static``으로 정의된 중첩(nested) 클래스는 외부 클래스를 참조하지 않는다.
방금 말한 static nested class가 정확히 Kotlin의 기본값이다.
class Button : View {
override fun getState(): State = ButtonState()
override fun restoreState(state: State) { /*...*/ }
class ButtonState: State { /*...*/ }
}
Kotlin의 내부 클래스는 기본적으로 외부 클래스를 참조할 수 없다. 외부 클래스를 참조할 수 있게 하고 싶다면 ``ButtonState``를 ``inner class``로 선언해야 한다.
정리하면 다음과 같다.
- 외부 클래스에 접근할 수 없는 nested class: ``static class A``(Java), ``class A``(Kotlin)
- 외부 클래스에 접근할 수 있는 inner class: ``class A``(Java), ``inner class A``(Kotlin)
'Primary > Kotlin' 카테고리의 다른 글
[Kotlin] for? forEach? (0) | 2022.05.25 |
---|---|
[Kotlin] sealed class (0) | 2022.05.20 |
[Kotlin] abstract class (0) | 2022.05.18 |
[Kotlin] Inline class (0) | 2022.05.04 |
[Kotlin] 코루틴의 실행 순서와 테스트 코드 (1) | 2022.04.26 |