본문 바로가기

Kotlin

Inner class 와 Nested Class 차이

작성 계기

두 class의 차이점에 대해 아느냐는 질문을 받은 적이 있는데, 사실 잘 몰라서 대답을 제대로 못했다

분명 썼을텐데 정확한 개념을 알고 쓰지는 않았던 것 같다

이제부터 알아보도록😄


inner class 와 nested class 모두 클래스 내부에 정의된 클래스를 말한다.

kotlin 에서는 별다른 키워드를 붙이지 않으면 클래스 내부에 정의된 클래스는 nested class로 만들어지며, 

inner 키워드를 붙여야 inner class로 만들어진다.

 

여기서 몇가지 질문이 생기는데

1. 왜 클래스 내부에 클래스를 쓰는가?

2. 왜 코틀린에서는 기본적으로 nested class를 사용하는가?

 

이에 대해 알아보자


Q1. 클래스 내부에 클래스를 왜 쓰는 걸까?

1 ) 외부 클래스에 대한 쉬운 접근을 하기 위해서

-> 내부 클래스는 외부 클래스의 private 멤버에도 접근할 수 있기 때문에, 외부 클래스와 긴밀한 연관성이 필요한 경우 사용할 수 있다.

 

2 ) 논리적으로 그룹화된 클래스를 만들기 위해서 (캡슐화를 위함)

-> 외부 클래스에서만 사용되는 클래스일 경우 외부로부터 은닉하기 위해 사용할 수 있다.


Q2. 왜 코틀린에서는 기본적으로 nested class를 사용하는가?

코틀린은 자바에서부터 출발했기 때문에, 자바에서의 문제점들을 개선한 부분이 많다.

자바에서는 기본적으로 내부 클래스에 대해 nested 가 아닌 inner 방식을 사용하는데,

이게 어떤 문제가 있었기 때문에 코틀린에서는 inner가 아닌 nested를 사용하도록 만든 것이다.

 

Inner class (외부 클래스 의존)

외부 클래스에 대한 참조를 유지하며 내부 클래스를 선언하는 것으로

다른 클래스에서는 사용할 수 없으며  오직 외부 클래스의 인스턴스 내부에서만 사용된다.

 

Nested class (외부 클래스에 독립적)

외부 클래스와 독립적으로 존재할 수 있는 클래스로 Inner와 다르게 외부에 대한 참조를 유지하지 않는다.

다른 클래스에서도 사용될 수 있다. 자바에서는 static 을 명시하여 nested class를 만들 수 있다.

 

왜 inner class가 문제가 되느냐? 그건 Effective Java 3. Item 24를 읽어보면 자세하게 알 수 있다.

이펙티브 자바에 관한 링크는 아래 첨부하도록 하고, 요약하자면 이런 문제가 발생할 수 있다.

 

1. 메모리 누수 문제

inner class와 같이 내부 클래스가 외부 클래스의 인스턴스를 참조할 때,

내부 클래스 인스턴스가 외부 클래스 인스턴스 보다 더 오래 살아 남을 경우 메모리 누수가 발생할 수 있다.

 

2. 더 안전하고 명확함

static 을 사용해 내부 클래스를 만든 nested class의 경우에는 외부 클래스와 독립적으로 존재하면서도

외부 클래스의 private 멤버에 접근이 가능하다. 외부 클래스에 대한 참조를 유지하지 않기 때문에 inner 보다 더 안전하면서도

inner의 기능을 할 수 있다.

 

관련 링크

 

[이펙티브 자바 3판] 아이템 24. 멤버 클래스는 되도록 static으로 만들라

[Effective Java 3th Edition] Item 24. Favor static member classes over nonstatic

madplay.github.io

 


결론 

1. 자바에서는 내부 클래스에 대해 기본적으로 inner class 방식을 사용하고 있었다.

1-1. 내부 클래스는 외부 클래스에 대한 접근을 쉽게 하기 위해 사용할 수 있다.

1-2. inner class는 외부 클래스의 인스턴스를 참조하는 방식을 통해 외부 클래스 멤버에 접근한다.

1-3. nested class는 외부 클래스와 독립적으로 존재하며, static 키워드를 통해 외부 클래스 멤버에 접근한다.

2. inner class 말고 nested class 방식을 사용하면 메모리 누수 문제를 해결할 수 있으면서도 캡슐화를 유지할 수 있다.

3. 그래서 코틀린에서는 기본적으로 nested class 방식을 사용하도록 구현되었다.

 

'Kotlin' 카테고리의 다른 글

코루틴 4장 : 코루틴의 실제 구현  (0) 2024.01.13
== 과 ===의 차이  (0) 2023.04.18
Flow 결합 연산자 : zip, combine  (0) 2023.04.11
operator fun invoke  (0) 2023.04.10
정렬  (0) 2023.01.09