Variance under inheritance
One of the ways we can learn about a concept is to ask questions that lead you to the concept. So let's ask a question ourselves. Given that a Cat
class type extends the Animal
class, is it okay to treat a list of cats as a list of animals? Programmatically, see the following:
abstract class Animal() class Cat(name: String) extends Animal() // Inheritance relationship between Cat and Animal def doSomethingForAnimals(animals: List[Animal]) = ??? //definitely do something for animals. Is it possible to pass an argument that's a list of Cats? val cats = List(new Cat("Mischief"), new Cat("Birdie")) doSomethingForAnimals(cats)
If it's possible, the statement that List[Cat]
is a subtype of List[Animal]
makes sense. Also, the concept is called covariance. Hence, we say List
is covariant in its type parameter T
:

If you take a look at the preceding image, the direction of the inheritance relationship between two concrete classes, namely Cat
and Animal...