[Kotlin] Kotlin Study #11

이제일·2023년 10월 22일
0

Kotlin

목록 보기
8/10

제네릭

  • 데이터의 타입의 일반화
  • 사용할 데이터 타입을 컴파일 시에 미리 지정하는 방법

문법 및 관용

  • 타입 매개변수는 꺽쇠 <> 괄호 안에 하나 이상 정의할 수 있음.
    보통 대문자 T, R, P, U를 사용
TypeFull namedesc
TType일반적으로 사용되는 타입 매개변수
EElement주로 Collection 요소의 타입을 나타내는 매개변수
KKeyMap에서 키의 타입을 나타내는 매개변수
VValueMap에서 값의 타입을 나타내는 매개변수
NNumber숫자 타입을 나타내는 매개변수
RReturn반환 타입을 나타내는 매개변수
S, U, V 등여러 개의 타입 매개변수가 필요한 경우, 추가적으로 사용될 수 있는 일반적인 알파벳

데이터 타입 지정

  • 콜론: 뒤에 특정 자료형 설정
  • 지정된 자료형과 그 하위 자료형만 제네릭 타입으로 지정 가능
  • 하나의 타입에 대해 여러개의 타입으로 제한하려면 where 키워드 설정
fun <T> useAndClose(input: T) where T: AutoCloseable, T: Appendable {
    input.append("there")
    input.close()
}

제네릭 활용

  • 확장함수
fun main() {
    println(1) // 1
    prefixPrint(1) // prefixed 1
}

fun <T> prefixPrint(obj: T) = println("prefixed " + obj.toString())
  • 클래스
fun main() {
    PrefixPrint(1) // prefixed 1
}

class PrefixPrint<T>(val obj: T){
    init{
        println("prefixed " + obj.toString())
    }
}
  • 인터페이스
fun main() {
    PrefixPrint(1) // prefixed 1
}

interface Prefixed<T> {
    fun getPrefixed(obj: T): String
}

class PrefixPrint<T>(val obj: T): Prefixed<T>{
    init{
        println(getPrefixed(obj))
    }
    override fun getPrefixed(obj: T) = "prefixed $obj"
}

제네릭 변성

따로 지정해주지 않으면 기본적으로 모든 Generic Class는 불변성(무공변성)이다.
따라서 해당 제네릭에 매칭되는 자료형만 대체되어 처리된다

제네릭 타입에 대해서 상속관계까지 처리하려면 변성(variance)을 지정해야함

종류로는 불변성(Invariance), 공변성(Covariance), 반공변성(Contravariance)의 세 가지가 존재

불변성(Invariance)

  • 설정한 자신의 타입만 허용
  • 제네릭 기본 설정
fun main() {
    val intObj: PrefixPrint<Int> = PrefixPrint<Int>(1) // prefixed 1
    // error by Type Mismatch
    // val anyObj: PrefixPrint<Any> = PrefixPrint<Int>(1)
}

class PrefixPrint<T>(val obj: T){
    init{
        println("prefixed " + obj.toString())
    }
}

공변성(Covariance)

  • out 키워드를 사용하여 설정
  • 자기 자신과 자식 타입 허용
  • 타입 매개변수를 메서드의 반환값으로 처리하는 연산만 제공하고, 입력값으로 사용할 수 없음
  • 따라서 타입 매개변수를 out 위치에서만 사용할 수 있는, 생산자로써의 역할만 수행

반공변성(Contravariance)

  • in 키워드를 사용하여 설정
  • 자기 자신과 상위 타입 허용
  • 타입 매개변수를 메서드의 파라미터로 처리하는 연산만 제공하고, 반환값으로 사용할 수 없음
  • 따라서 타입 매개변수를 in 위치에서만 사용할 수 있는, 소비자로써의 역할만 수행

profile
세상 제일 이제일

0개의 댓글