O'Reilly logo

Programming Scala by Alex Payne, Dean Wampler

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Variance Under Inheritance

An important difference between Java and Scala generics is how variance under inheritance works. For example, if a method has an argument of type List[AnyRef], can you pass a List[String] value? In other words, should a List[String] be considered a subtype of List[AnyRef]? If so, this kind of variance is called covariance, because the supertype-subtype relationship of the container (the parameterized type) “goes in the same direction” as the relationship between the type parameters. In other contexts, you might want contravariant or invariant behavior, which we’ll describe shortly.

In Scala, the variance behavior is defined at the declaration site using variance annotations: +, -, or nothing. In other words, the type designer decides how the type should vary under inheritance.

Let’s examine the three kinds of variance, summarized in Table 12-1, and understand how to use them effectively. We’ll assume that Tsup is a supertype of T and Tsub is a subtype of T.

Table 12-1. Type variance annotations and their meanings

AnnotationJava equivalentDescription

+

? extends T

Covariant subclassing. E.g., List[Tsub] is a subtype of List[T].

-

? super T

Contravariant subclassing. E.g., X[Tsup] is a subtype of X[T].

none

T

Invariant subclassing. E.g., Can’t substitute Y[Tsup] or Y[Tsub] for Y[T].

The “Java equivalent” column is a bit misleading; we’ll explain why in a moment.

Class List is declared List[+A], which means that List[String] is a subclass of List[AnyRef], so Lists are covariant ...

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required