Home 중첩 클래스와 내부 클래스
Post
Cancel

중첩 클래스와 내부 클래스

중첩 클래스 (Nested Class)

정의

  • 하나의 클래스가 다른 클래스의 기능과 강하게 연관되어 있다는 의미를 전달하기 위해 만들어진 형식
  • 클래스 안에 또 다른 클래스가 정의되는 것

사용법

  • 한 클래스안에 다른 클래스를 정의하면 기본적으로는 중첩 클래스가 된다. (조금 있다가 배우겠지만 여기에 inner 키워드를 추가하면 내부 클래스가 된다.)
    • 외부클래스 이름.중첩클래스 이름” 으로 참조

내부 클래스 (Inner Class)

정의

  • 중첩 클래스는 형태만 내부에 존재할 뿐 실질적으로는 서로 내용을 직접 공유할 수 없는 별개의 클래스
  • 내부 클래스는 외부 클래스 객체 안에서 사용되는 클래스이므로 외부 클래스 객체의 속성이나 함수를 사용할 수 있다.

사용법

  • 중첩 클래스에 inner라는 키워드를 붙여서 사용
    • outer 클래스와 inner 클래스에 같은 이름의 속성이나 함수가 있다면 “this@외부클래스 이름” 으로 참조
  • 내부 클래스는 혼자서 객체를 만들 수는 없고 외부 클래스의 객체가 있어야만 생성과 사용이 가능한 클래스
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
31
32
33
34
class Outer{
    var text = "Outer Class"
    
    class Nested{
        fun introduce(){
            println("Nested Class")
        }
    }
    
    inner class Inner{
        var text = "Inner Class"
        
        fun introduceInner(){
            println(text) // println(this@Inner.text) 와 같다.
        }
        fun introduceOuter(){
            println(this@Outer.text) //외부 클래스에 있는 text와 이름이 같으므로 this@Outer로 참조
        }
    }
}

fun main(){
    Outer.Nested().introduce()
    
    val outer = Outer()
    val innerC = outer.Inner() // 혹은 바로 Outer().Inner()로도 선언 가능
    
    innerC.introduceInner()
    innerC.introduceOuter()
    
    outer.text = "Changed Outer text"
    innerC.introduceOuter()
}

참고사항

  • 내부 클래스는 기본적으로 외부 클래스를 참조하여 객체에 접근이 가능하지만 중첩 클래스는 그렇지 않다.
1
2
3
4
5
6
7
8
9
10
11
12
13
class Outer{
    var text = "Outer Class"
    class Nested{
        fun introduce(){
            println("Nested Class, ", text) // 오류: text 참조 불가능 
        }
    }
    
}

fun main(){
    Outer().Nested().introduce() //오류: Nested()는 Outer() 클래스의 내부 클래스가 아니므로 참조 불가
}
  • 기본은 Nested Class를 사용하는 것이 좋다. (Inner classes는 정말 필요치 않으면 쓰지 않는 게 좋다)
    • Outer를 참조할 필요가 없다면 굳이 inner를 명시할 필요는 없고, 불필요한 메모리 낭비를 사전에 막을 수 있다.
  • Inner classes를 보호하고 싶다면 private를 명시하자.

자바의 Nested Class

  • 코틀린은 클래스 안에 다른 클래스를 선언하면 기본적으로 ‘중첩 클래스’이지만, 자바는 ‘내부 클래스’가 기본
    • 자바에서는 static을 선언해야 중첩 클래스가 된다.
    • Inner classes를 허용하는 자바는 Outer를 참조하지 않아도 기본 inner classes이기 때문에 불필요한 메모리 낭비와 성능 이슈를 야기
    • Inner classes 내부에 숨겨진 Outer class 정보를 보관하게 되고, 결국 참조를 해지하지 못하는 경우가 생기면 메모리 누수 발생 가능, 코드를 분석하더라도 이를 찾기 쉽지 않아 해결하지 못하는 경우도 발생
  • 자바의 이러한 문제점 때문에 코틀리에서는 자바와 반대로 기본은 ‘중첩 클래스’, inner를 선언하면 ‘내부 클래스’가 된다.