class: class CatShelter extends AnimalShelter { void putAnimal(covariant Cat animal) { // ... } } This is not type safe. By up-casting a to an , one can try to place a dog in a cat shelter. That does not meet parameter restrictions, and will result in a runtime error. The lack of type safety (known as the "catcall problem" in the Eiffel community, where "cat" or "CAT" is a Changed Availability or Type) has been a long-standing issue. Over the years, various combinations of global static analysis, local static analysis, and new language features have been proposed to remedy it, and these have been implemented in some Eiffel compilers. Despite the type safety problem, the Eiffel designers consider covariant parameter types crucial for modeling real world requirements. The cat shelter illustrates a common phenomenon: it is a kind of animal shelter but has additional restrictions, and it seems reasonable to use inheritance and restricted parameter types to model this. In proposing this use of inheritance, the Eiffel designers reject the Liskov substitution principle, which states that objects of subclasses should always be less restricted than objects of their superclass. One other instance of a mainstream language allowing covariance in method parameters is PHP in regards to class constructors. In the following example, the __construct() method is accepted, despite the method parameter being covariant to the parent's method parameter. Were this method anything other than __construct(), an error would occur: interface AnimalInterface {} interface DogInterface extends AnimalInterface {} class Dog implements DogInterface {} class Pet { public function __construct(AnimalInterface $animal) {} } class PetDog extends Pet { public function __construct(DogInterface $dog) { parent::__construct($dog); } } Another example where covariant parameters seem helpful is so-called binary methods, i.e. methods where the parameter is expected to be of the same type as the object the method is called on. An example is the method: checks whether comes before or after in some ordering, but the way to compare, say, two rational numbers will be different from the way to compare two strings. Other common examples of binary methods include equality tests, arithmetic operations, and set operations like subset and union. In older versions of Java, the comparison method was specified as an interface : interface Comparable { int compareTo(Object o); } The drawback of this is that the method is specified to take an argument of type . A typical implementation would