Page 22 -
P. 22

private set

                   val children: List<TreeNode<T>> get() = _children

                   fun addChild(data: T) = TreeNode(data).also {
                     _children += it
                     it.parent = this
                   }

                   override fun toString() =
                     _children.joinToString(prefix = "$data {", postfix = "}")
                 }

                 fun main() {
                   val root = TreeNode("Hello").apply {
                     addChild("World")
                     addChild("!!!")
                   }

                   println(root) // Hello {World {}, !!! {}}
                 }


               클래스의 타입 파라미터를 각괄호 안에 써야 한다. 타입 파라미터는 클래스 이름 바로 뒤에 온다.
               타입 파라미터 이름은 아무 이름이나 가능하지만, 관습적으로 T, U, V 등의 (짧은) 대문자를 사용
               한다. 클래스 안에서는 타입 파라미터를 변수나 프로퍼티, 함수의 타입이나 다른 제네릭 선언의
               타입 인자로 쓸 수 있다.

                자바 vs. 코틀린  제네릭 클래스나 인터페이스를 사용해 데이터의 타입을 지정할 때는 반드시 타입
               인자를 명시해야 한다. TreeNode처럼 타입 파라미터를 지정하지 않은 로타입(raw type)을 사용할

               수 있는 자바와 달리, 코틀린에서는 이를 허용하지 않는다. 코틀린에서는 TreeNode<String>처럼
               구체적인 타입을 지정하거나, TreeNode<U>처럼 타입 인자로 받은 타입을 반드시 지정해야 한다.

               제네릭 클래스 생성자를 호출할 때는 타입 인자가 불필요한 경우가 자주 있다. 대부분의 경우 컴
               파일러가 문맥에서 타입 인자를 추론해준다. 그러므로 앞의 예제 코드에서 TreeNode("Hello")처
               럼 생성자를 호출할 수 있다. 다만 상위 클래스 생성자에 대한 위임 호출은 예외다. 예제 코드를
               약간 바꿔보자.


                 open class DataHolder<T>(val data: T)

                 // 실제 타입을 상위 타입의 타입 인자로 넘김


         362





     Kotlin_05.indd   362                                                                    2022-02-15   오후 4:08:04
   17   18   19   20   21   22   23   24   25   26   27