Variance
- Kotlin course
- Intermediate
- Lesson 49/116
- 5 min
Learn in, out and variance concepts.
Variance
Variance describes the subtype relation between generic types. Kotlin uses out (covariance) and in (contravariance) keywords.
Example: interface Producer<out T> { fun produce(): T }. out T means T is used only in an producing (out) position. Producer<Int> becomes a subtype of Producer<Number>. in T means T is used only in a consuming (in) position. Variance gives flexibility in generic APIs.
out vs in
out and in describe opposite directions. out T only produces the type; in T only consumes it.
Example: interface Producer<out T> { fun produce(): T }; interface Consumer<in T> { fun consume(t: T) }. Producer<Int> can be used as a Producer<Number> (Int is a subtype of Number). Consumer<Number> can be used as a Consumer<Int>. Variance makes generic types fit the subtype hierarchy. This adds flexibility in function parameters.
Practice The Producer<T> generic interface
Define an interface interface Producer<out T> with a fun produce(): T method. Define a class class IntProducer(val value: Int) : Producer<Int> with override fun produce(): Int = value. In main declare val p: Producer<Number> = IntProducer(42) and print the result with println(p.produce()).
Starter code
// Define the Producer interface (covariance)
// IntProducer class and produce method
// use it as Number in main and printSample solution
interface Producer<out T> {
fun produce(): T
}
class IntProducer(val value: Int) : Producer<Int> {
override fun produce(): Int = value
}
fun main() {
val p: Producer<Number> = IntProducer(42)
println(p.produce())
}Expected output
42
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Complete the out variance definition
interface Producer<____ T> {
fun produce(): T
}
interface Producer<out T> {
fun produce(): T
}
Explanation: out T marks a producer position.
2 Match the variance parts
| Term | Meaning |
|---|---|
out T |
Producer (covariance) |
in T |
Consumer (contravariance) |
fun produce(): T |
Producing method |
fun consume(t: T) |
Consuming method |
3 What does <code>out</code> specify in <code>interface Producer<out T></code>?
- That T is only produced Correct answer
- That T is only consumed
- That T is mutable
- That T is nullable
Explanation: out T means T is only produced.