Frequently it seems like it would be nice if when a method is
overridden we could change the argument types or return types.
A change that moves down the inheritance hierarchy, making it more
specific, is said to be covariant. A change that moves up the inheritance
hierarchy is said to be contravariant.
class Parent {
void test (covar : Mammal, contravar : Mammal) : boolean
}
class Child extends Parent {
void test (covar : Cat, contravar : Animal) : boolean
}
While appealing, this idea runs into trouble with the principle of
substitution.
Parent aValue = new Child();
aValue.text(new Dog(), new Mammal()); // is this legal??