# Covariance, inversion, upper bound, lower bound, etc. in Scala

2021-10-22 10:58:09

# Catalog [−]

Scala Covariant inversion and Java The covariant inversion in is different , It looks more complicated . This paper deals with Scala Make a summary of these concepts in .
First, let's look at some concepts ：

• covariant Covariance . Enables you to use subclasses of types larger than originally specified
• Contravariance Inversion . Enables you to use a parent class of a type larger than the originally specified type .
• Invariance unchanged . You can only use the original specified type , No covariance or inversion
• Upper bounds upper bound .
• Lower bounds Lower bound .

### Java The covariance and contravariant in

First of all, let's review Java The covariance and contravariant in , It makes it easier for us to understand Scala The covariance and contravariant in .
1 Covariance

Sub.getSomething() Is a covariant type , Because its return type is Super.getSomething Subclass of return type .

2 Inversion

Sub.getSomething() Is an inverse type , Because its input parameter is Super.getSomething The parent class of the input parameter .

3 Generic
There are also covariants and inversions in generics .

You can call `covariantList` All methods that do not require generic parameters , Because generic parameters must extends Object, But you don't know its exact type at compile time . But you can call getter Method , Because the return type always matches Object type .
`contravariantList` Just the opposite , You can call all methods with generic parameters , Because you can definitely pass in a String Parent class of . however getter The method doesn't work .

### Scala The covariance of

The first thing we need to know is subtypes (subtyping). A class can be a subclass of other classes (sub-) Or the parent class (super-). We can use mathematical concepts (partial order) To define :

When we define a covariant type `List[A+]` when ,List[Child] It can be List[Parent] Subtypes of .
When we define an inverse type `List[-A]` when ,List[Child] It can be List[Parent] The father type of .

See the following example ：

`c` Cannot assign a value to `c2`, because `Consumer` Defined as an invariant type .

A little change ：

because `Consumer` Defined as covariant , therefore `Consumer[Bird]` yes `Consumer[Animal]` Subtypes of , So it can be assigned to `c2`.

### Scala The inverse of

Change the above example ：

here `Consumer[-T]` Defined as an inverse type , therefore `Consumer[Bird]` Regarded as `Consumer[Hummingbird]` Subtypes of , so `c` Can be assigned to `c2`.

### Lower bound lower bounds

If the covariant class contains methods with type parameters ：

Compilation error . The error message is "Covariant type T occurs in contravariant position in type T of value t".
However, if the returned result is a type parameter, there is no problem .

To use type parameters in method parameters , You need to define the lower bound ：

### upper bound upper bounds

Examples of using upper bounds in inverse classes ：

You can see that the return value of the method is of covariant type , The parameter of the method is the inverse type .
Therefore, the type parameter of covariant class can be used in the type of return value of method , A lower bound must be used on the parameter type of the method `>:`.
The type parameter of the inverse class can be used on the parameter type of the method , When used as the return value type of a method, you must use the upper bound binding `<:`.

### Comprehensive covariance , Inversion , upper bound , Lower bound

A comprehensive example ：

### View Bound `<%`

Scala There is also a view binding function , Such as

Or type parameters on methods ：

It requires T There must be an implicit conversion to Bird, That is to say `T => Bird`, Otherwise, the above code will compile incorrectly ：

Add an implicit conversion , Compile and pass .

### Context Bound

context bound stay Scala 2.8.0 Introduction in , Also known as type class pattern.
view bound Use `A <% String` The way ,context bound You need a parameterized type , Such as `Ordered[A]`.
It declares a type `A`, Implicitly there is a type `B[A]`, The grammar is as follows ：

A clearer example ：

And such as

### Reference documents

https://chowdera.com/2021/10/20211009000611674i.html