제네릭이란?
제네릭은 타입 정보를 매개변수화하고 싶을 때 유용하게 사용하는 기법을 말한다.
즉 type을 호출할 때 파라미터 값을 넣어주는 것처럼 넣어주는 것이라고 생각하면 될 것 같다.
그럼 우리가 제네릭을 사용해야 하는 이유를 알아보자
content를 Int type으로 반환하는 class
class Test1(var content:Int) {
fun replace(content:Int) {
this.content = content
}
fun get(): Int{
return content
}
}
content를 String type으로 반환하는 class
class Test1(var content:String) {
fun replace(content:String) {
this.content = content
}
fun get(): String{
return content
}
}
사실상 완전히 같은 역할을 수행하는데 type이 다르다는 이유로 두 개의 클래스를 정의해야한다는 점이 불편하다.
제네릭 사용
그럼 제네릭을 사용해보자
class Box<T>(var content: T){
fun replace(content: T){
this.content = content
}
fun get(): T{
return content
}
}
이렇게 T 를 통해 Type을 밭을 수 있다.
그럼 왜 T인가? 라는 생각이 든다.
보통 Type의 약자를 따서 T라고 하고
T의 타입정보는 클래스를 정의하는 시점에서 정해지지 않고 나중에 객체를 생성하는 시점에서 생성된다고 한다.
위에 제네릭을 사용한 함수를 호출해보자
val testValue = Box<Int>(4)
val testValue2 = Box("hello")
println(testValue.get())
println(testValue.get())
출력 값은
4
Hello
이다.
보면 Box<Int>로 type을 설정해주기도 하지만
그냥 testValue2 객체처럼 Box("hello")로 해주기도 한다.
그 이유는 코틀린의 type inference (타입 추론) 기능이 있기 때문에 String 값이라고 추론이 가능하다.
이외 사용
두 타입을 지정하는 클래스
data class MyPair<FirstType,SecondType>(
var first:FirstType, var second:SecondType)
이런식으로도 정의가 가능하다.
FirstType과 SecondType을 받아서 매개변수로 받는 first와 second의 각각 type을 지정해 줄 수 있다.
--간단하지만 제네릭의 핵심적인 부분을 정리했다고 생각한다. 유용한 블로그가 되었음 좋겠다.--