# Variance¶

**Note:** This is an advanced section. Feel free to skip it initially.

Variance deals with the question, which generic types are compatible with each other. We explain this concept using the following class:

The class is called `Stack`

and has a single type parameter, which is supposed to the denote the type of the elements of the stack. With its [constructor], we can specify the initial elements of the stack. Moreover, two methods are defined on the stack:

`push`

is supposed to add a new element to the top of the stack.`pop`

is supposed to remove and return the topmost element of the stack.

We will now try to answer the following two questions:

- If
`A`

is a subclass of`B`

, can we assign`Stack<A>`

to`Stack<B>`

? - If
`B`

is a subclass of`A`

, can we assign`Stack<A>`

to`Stack<B>`

?

## Invariance¶

By default, the answer to both questions is "no". The reason for this is that it can allow illegal behavior:

Say, we expect a `Stack<Number>`

, but pass a `Stack<Int>`

(`Int`

is a subclass of `Number`

). If we can treat the `Stack<Int>`

as a `Stack<Number>`

, we are also allowed to add values of type `Float`

to it. This would also change the original `Stack<Int>`

, which now contains illegal floating point values.

Now, imagine we a `Stack<Number>`

, but pass a `Stack<Any>`

(`Number`

is a subclass of `Any`

). If we can treat the `Stack<Any>`

as a `Stack<Number>`

, we could read values from the stack that are not numbers, for example strings, since the original stack can contain `Any`

value.

To sum this up, we cannot assign `Stack<A>`

to `Stack<B>`

if `A`

is a subclass of `B`

because we might write to the `Stack<B>`

and alter the original `Stack<A>`

in an illegal way. Likewise, we cannot assign `Stack<A>`

to `Stack<B>`

if `B`

is a subclass of `A`

because we might read something from the `Stack<B>`

that is not of type `B`

.

We say, the type parameter `T`

of the class is invariant. It must be matched exactly. The conditions we describe above, however, already give us the information under which circumstances we can loosen this requirement.

## Covariance¶

We now want a `Stack<A>`

to be assignable to a `Stack<B>`

if `A`

is a subclass of `B`

. This behavior is called *covariance* since the type compatibility relation between `Stack<A>`

and `Stack<B>`

points in the same direction as the type compatibility relation between `A`

and `B`

.

As outlined above, we can only allow covariance if we forbid writing access. This means that a type parameter that is covariant can only be used for reading. Concretely, a covariant type parameter can only be used as the type of a result not the type of a parameter. We also say the type parameter can only be used in the *out-position* (i.e. as output), which motivates the keyword `out`

to denote covariance (see Section Specifying Variance).

In the `Stack`

example, we can make the class covariant by adding the keyword `out`

to the type parameter `T`

and removing the writing method `push`

:

## Contravariance¶

We now want a `Stack<A>`

to be assignable to a `Stack<B>`

if `B`

is a subclass of `A`

. This behavior is called *contravariance* since the type compatibility relation between `Stack<A>`

and `Stack<B>`

points in the opposite direction as the type compatibility relation between `A`

and `B`

.

As outlined above, we can only allow contravariance if we forbid reading access. This means that a type parameter that is contravariant can only be used for writing. Concretely, a contravariant type parameter can only be used as the type of a parameter not the type of a result. We also say the type parameter can only be used in the *in-position* (i.e. as input), which motivates the keyword `in`

to denote contravariance (see Section Specifying Variance).

In the `Stack`

example, we can make the class contravariant by adding the keyword `in`

to the type parameter `T`

and removing the reading method `pop`

:

## Specifying Variance¶

The variance of a type parameter can only be declared at its declaration site, using the syntax shown in the following table:

Desired Variance | Declaration Site |
---|---|

Invariant | `class Stack<T>` |

Covariant | `class Stack<out T>` |

Contravariant | `class Stack<in T>` |