KOTLIN · 객체지향
고급 제네릭 — in/out variance
Kotlin의 out(공변)과 in(반공변) 키워드는 제네릭 타입의 변성(variance)을 선언합니다. Java의 ? extends T와 ? super T를 대체하며, 타입 안전한 제네릭 API 설계에 필수적입니다.
핵심 설명
Kotlin의 out(공변)과 in(반공변) 키워드는 제네릭 타입의 변성(variance)을 선언합니다. Java의 ? extends T와 ? super T를 대체하며, 타입 안전한 제네릭 API 설계에 필수적입니다.
Kotlin code
// out = 공변 (Producer): T를 반환만 함
interface Producer<out T> {
fun produce(): T
// fun consume(item: T) // 컴파일 오류! out 타입은 입력 불가
}
// in = 반공변 (Consumer): T를 소비만 함
interface Consumer<in T> {
fun consume(item: T)
// fun produce(): T // 컴파일 오류! in 타입은 반환 불가
}
// 무공변 (Invariant): T를 입출력 모두 사용
interface Transformer<T> {
fun transform(item: T): T
}
open class Animal(val name: String)
class Dog(name: String) : Animal(name)
class Cat(name: String) : Animal(name)
class DogProducer : Producer<Dog> {
override fun produce() = Dog("멍멍이")
}
class AnimalConsumer : Consumer<Animal> {
override fun consume(item: Animal) {
println("동물 처리: ${item.name}")
}
}
fun feedAnimals(producer: Producer<Animal>, consumer: Consumer<Dog>) {
val animal = producer.produce()
consumer.consume(Dog("강아지"))
}
fun main() {
// out: Dog는 Animal의 하위 → Producer<Dog>는 Producer<Animal>의 하위
val dogProducer: Producer<Animal> = DogProducer() // OK!
println(dogProducer.produce().name)
// in: Animal은 Dog의 상위 → Consumer<Animal>은 Consumer<Dog>의 하위
val animalConsumer: Consumer<Dog> = AnimalConsumer() // OK!
animalConsumer.consume(Dog("바둑이"))
feedAnimals(DogProducer(), AnimalConsumer())
}학습 팁
기억법: out은 "나가기만"(produce), in은 "들어오기만"(consume). List<out T>는 읽기 전용이라 List<Dog>를 List<Animal>로 안전하게 사용할 수 있습니다.
주의할 점
타입 파라미터에 out을 선언하면 해당 타입을 함수 매개변수(입력 위치)에 사용할 수 없습니다. 입출력 모두 필요하면 변성을 선언하지 말고 사용처 변성(use-site variance)을 활용하세요.
자주 묻는 질문
고급 제네릭 — in/out variance란 무엇인가요?
Kotlin의 out (공변)과 in (반공변) 키워드는 제네릭 타입의 변성(variance)을 선언합니다. Java의 ? extends T 와 ? super T 를 대체하며, 타입 안전한 제네릭 API 설계에 필수적입니다.
고급 제네릭 — in/out variance 학습 시 주의할 점은 무엇인가요?
타입 파라미터에 out 을 선언하면 해당 타입을 함수 매개변수(입력 위치)에 사용할 수 없습니다. 입출력 모두 필요하면 변성을 선언하지 말고 사용처 변성(use-site variance)을 활용하세요.
Continue Learning
Kotlin 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.