Variance (Covariant/Contravariant)
In this page:
class Box[+T](value: T) // covariant
trait Handler[-T] // contravariant
Variance (Covariant/Contravariant)
Covariance, declared with class Box[+T], lets Box[Dog] be used where Box[Animal] is expected, preserving the subtype relationship of the type parameter.
Contravariance, declared with class Printer[-T], works the opposite direction -- a Printer[Animal] can be used where a Printer[Dog] is expected, since it can handle anything an Animal-or-more-general printer could. By default (no +/-), a type parameter is invariant, meaning no such substitution is allowed at all.
Example: Variance (Covariant/Contravariant)
class Animal(val name: String)
class Dog(name: String) extends Animal(name)
class Box[+T](val item: T)
object Main extends App {
val dogBox: Box[Dog] = new Box(new Dog("Rex"))
val animalBox: Box[Animal] = dogBox // allowed because Box is covariant
println(animalBox.item.name)
}
Login to try C/C++/Java/PHP code in the editor
- Declaring a mutable field of a covariant type, like
class Box[+T](var item: T), which does not compile. - Assuming
Box[Dog]is aBox[Animal]without+T, since Scala classes are invariant by default. - Mixing up
+Tand-T, when covariance is for producers and contravariance for consumers.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: