用子接口作为新参数覆盖方法参数
我不知道为什么此代码在PHP中不起作用?
I cant figure out why this code does not work in PHP?
<?php
interface Engine {
function run();
}
interface HydroEngine extends Engine {
function run();
}
interface Car {
function setEngine(Engine $engine);
}
interface WaterCar extends Car {
function setEngine(HydroEngine $engine);
}
?>
似乎没有违反任何OOP规则,但是为什么会给我一个错误?
It seems it does not break any OOP rules, but why it gives me an error?
Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)
它确实中断了 SOLID 规则.您声明Car::setEngine
接受类型为Engine
的一个参数,但是子级WaterCar::setEngine
接受类型为HydroEngine
的参数.即使HydroEngine
是Engine
的子类型,它仍然是不同的类型.
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.
当一个类为Foo implements WaterCar
时,该类为instanceof Car
也是正确的.但是Foo::setEngine
接受HydroEngine
,但不接受Engine
.因此,Foo::setEngine
应该是implements Car
,但不接受Engine
类型的参数.这违反了 Liskov替代原则.您不能在子类化接口中更改参数类型,即周期.
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.
用于继承的关键字显式为 extends
.子类与父类确实完全相同,甚至可能与父类完全相同.它不能比父对象做得少.由于HydroEngine
是Engine
的特殊子类型,因此这意味着WaterCar
比Car
做更少,因为它只接受更窄的Engine
子类型.例如:
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);
}
如果您传入WaterCar
,则上面的代码会崩溃,因为它不接受Engine
.
The above code would implode if you passed in a WaterCar
, because it does not accept an Engine
.