Type variance is a design decision we have to make when we create a class with a type parameter, also known as a generic type. We have 3 options listed bellow:

1. Non Variant type

So this is the definition:

At this point our GenericType has no type variance, which means we cannot substitute NonVariantType[String] with a NonVariantType[Any] or the other way around. This is demonstrated bellow:

2. Covariant Type

If we expect our generic type to work with subtypes of our type parameter in the same way as the type we instantiate it with, then we define our type as a covariant type:

So with our new definition we repeat our example from before using our covariant type:

3. Contravariant Type

If we expect our generic type to work with supertypes of our type parameter in the same way as they type we instantiate it with, then we define our type as a contravariant type:

And finally with the contravariant definition we have our example looking like this:

Here I tried to list the simplest ways your generic types can be defined over their parameter type without going into much detail, following posts will deal with the details of selecting each one.