The most commonly contravariant parameters are used in functions and function-like structures (callbacks, visitors, etc...). Look at the documentation of
Function1 and
Function2. Parameters to these functions are contra-variant. In very basic terms it means that "if function accepts object, then it can accept string (or any other reference)". So you can write
This works quite well with the following rules:
* If you are going to return value of T, T can be covariant. If your method (or methods in class) returns an instance of some class, we can use that method or class where users expect an object of superclass to be returned.
* If you are going to receive an argument of type T, T can be contravariant. If your method (or methods in a class) can accept objects of some class, it can accept an object of subclass.
* If you are going to accept and return values of T, then T can't be neither covariant nor contravariant. Mutable collections like ArrayBuffer are example of this rule.