기록
[코틀린/Kotlin] 캐스팅을 줄여주는 제너릭 본문
클래스나 함수에서 사용하는 자료형을 외부에서 지정할 수 있는 기능인 제너릭에 대해 알아보자.
클래스 A와 A 클래스를 상속바는 클래스 B가 있다고 해보자.
이 두 클래스의 인스턴스를 공용으로 사용하는 하나의 함수에 파라미터로 담으려면 어떻게 해야할까?
fun castingExam(var a: A)
지난 강의에서 보았듯 수퍼클래스인 A의 자료형으로 받으면 B를 넣어도 A로 캐스팅 되어, 두 클래스 모두 함수의 파라미터로 사용할 수 있다.
하지만, 캐스팅 연산을 사용하는 것은 프로그램의 속도를 저하시킬 수 있다는 단점이 있다.
그래서 나온 것이 제너릭이라는 개념이다.
제너릭은 함수나 클래스를 선언할 때 고정적인 자료형 대신 실제 자료형으로 대체되는 타입 파라미터를 받아 사용하는 방법이다.
타입 파라미터에 특정 자료형이 할당되면, 제너릭을 사용하는 모든 코드는 할당된 자료형으로 대체되어 컴파일 된다.
따라서 캐스팅 연산 없이도 자료형을 그대로 사용할 수 있다.
타입 파라미터의 이름은 일반적으로 'Type'의 이니셜인 'T'를 사용하는 것이 관례이며, 여러개의 제너릭을 사용할 경우 U와 V를 추가적으로 사용하기도 한다.
fun <T>genericFunc (param: T):T
class GenericClass<T> (var pref: T)
또한, 제너릭을 특정한 수퍼 클래스를 상속받은 클래스 타입으로만 제한하려면 콜론을 쓰고 SuperClass를 명시하면 된다.
1. 클래스에서의 사용
클래스에 제너릭을 선언한 경우, 인스턴스를 만들 때 타입 파라미터를 수동으로 지정하거나 생성자에 제너릭이 사용된 경우 지정하지 않아도 자동으로 추론된다.
UsingGeneric클래스에서 수퍼클래스를 A로 제한한 제너릭 T를 선언하고 생성자에서는 제너릭 T에 맞는 인스턴스를 속성 t로 받아보자.
fun main() {
UsingGeneric(A()).doShouting()
UsingGeneric<B>(B()).doShouting()
//위와 같이 타입 파라미터를 수동으로 전달할 수 있지만
//생성자의 파라미터에 의해 클래스 A라는 것을 알 수 있기 때문에 생략 가능하다.
}
open class A {
open fun shout() {
println("A가 소리칩니다")
}
}
class B: A() {
override fun shout() {
println("B가 소리칩니다")
}
}
class UsingGeneric <T: A> (val t: T) {
fun doShouting() {
t.shout()
}
}
제너릭을 사용하지 않고 UsingGeneric의 생성자에서 수퍼클래스 A로 캐스팅해도 동작은 같겠지만, 이렇게 제너릭을 사용하면 제너릭이 자료형을 대체하게 되어 캐스팅을 방지하여 성능을 더 높일 수 있다.
2. 함수에서의 사용
이번엔 Generic을 함수에 사용해보자.
함수에 제너릭을 선언한 경우, 일반적인 함수처럼 사용하면 파라미터나 반환형을 통해 타입 파라미터를 자동으로 추론해준다.
fun main() {
doShouting(B())
}
fun <T: A> doShouting(t: T) {
t.shout()
}
open class A {
open fun shout() {
println("A가 소리칩니다")
}
}
class B: A() {
override fun shout() {
println("B가 소리칩니다")
}
}
함수 또한 제너릭의 타입을 자동으로 추론하므로 별도로 타입 파라미터에 자료형을 전달할 필요는 없다.
역시 캐스팅 없이 B의 객체 그대로 함수에서 사용한다.
제너릭은 많은 기본 클래스에서도 사용되고 있으니 꼭 알아두자.
https://www.youtube.com/watch?v=q7GV68jKLVM&list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN&index=19
위 강의를 보면서 개인적으로 공부한 내용을 정리하였습니다.
'[Study] > Kotlin' 카테고리의 다른 글
[코틀린/Kotlin] 문자열을 다루는 법 (0) | 2022.05.09 |
---|---|
[코틀린/Kotlin] 데이터를 담는 리스트 (0) | 2022.05.09 |
[코틀린/Kotlin] 클래스의 다형성 (as, is) (0) | 2022.05.09 |
[코틀린/Kotlin] Object, Companion Object (0) | 2022.05.08 |
[코틀린/Kotlin] 람다함수의 특별한 케이스(it), 스코프 함수(apply, run, with, also, let) (0) | 2022.05.07 |