Chapter 10. The Scala Object System, Part I
We’ve learned a lot about Scala’s implementation of object-oriented programming. In this chapter, we’ll discuss more details of the type hierarchy in the standard library, exploring some of those types in depth, such as
But first, let’s discuss an important feature of the type system called variance under inheritance, which we’ll need to understand before discussing several of the library types described later in this chapter.
We’ll conclude with a discussion of object equality.
Parameterized Types: Variance Under Inheritance
An important difference between Java’s and Scala’s parameterized types (usually called generics in the Java literature) is how variance under inheritance works.
For example, suppose a method takes 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 true, 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.
We can also have types that are contravariant, where
X[String] is a supertype of
X[Any], for some type
If a parameterized type is neither covariant nor contravariant, it is called invariant. Conversely, some parameterized types can mix two or more of these behaviors.
Both Java and Scala support covariant, contravariant, and invariant types. However, ...