It does break SOLID rules. You declare Car::setEngine
to accept one parameter of type Engine
, but the child WaterCar::setEngine
accepts a parameter of type HydroEngine
. Even if HydroEngine
is a subtype of Engine
, it’s still a different type.
When a class Foo implements WaterCar
, it is also true that this class is an instanceof Car
. But Foo::setEngine
accepts a HydroEngine
, but does not accept an Engine
. So Foo::setEngine
supposedly implements Car
, yet does not accept a parameter of type Engine
. Which breaks the Liskov substitution principle. You cannot change the type of parameters in subclassed interfaces, period.
The keyword for inheritance is explicitly extends
. A subclass does exactly the same as the parent class and possibly more. It cannot do less than the parent. Since HydroEngine
is a specialized subtype of Engine
, this would mean a WaterCar
does less than a Car
, since it only accepts a more narrow subtype of Engine
. E.g.:
function (Car $car) {
$engine = new EngineImplementation;
$car->setEngine($engine);
}
The above code would implode if you passed in a WaterCar
, because it does not accept an Engine
.