Ответ 1
Он нарушает правила SOLID. Вы объявляете Car::setEngine
принимать один параметр типа Engine
, но дочерний элемент WaterCar::setEngine
принимает параметр типа HydroEngine
. Даже если HydroEngine
является подтипом Engine
, он все еще отличается от типа.
Когда класс Foo implements WaterCar
, также верно, что этот класс является instanceof Car
. Но Foo::setEngine
принимает HydroEngine
, но не принимает Engine
. Итак, Foo::setEngine
предположительно implements Car
, но не принимает параметр типа Engine
. Что нарушает принцип замещения Лискова. Вы не можете изменить тип параметров в подклассах интерфейсов, период.
Ключевое слово для наследования явно extends
. Подкласс делает то же самое, что и родительский класс и, возможно, больше. Он не может делать меньше, чем родитель. Так как HydroEngine
является специализированным подтипом Engine
, это означает, что WaterCar
делает меньше, чем a Car
, поскольку он принимает только более узкий подтип Engine
. Например:.
function (Car $car) {
$engine = new EngineImplementation;
$car->setEngine($engine);
}
Вышеприведенный код будет развязываться, если вы передали в WaterCar
, потому что он не принимает Engine
.