使用子接口作为新参数覆盖方法参数 [英] Override method parameter with child interface as a new parameter

查看:29
本文介绍了使用子接口作为新参数覆盖方法参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么这段代码在 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?

致命错误:WaterCar::setEngine() 的声明必须与 Car::setEngine(Engine $engine) 兼容

推荐答案

确实打破了SOLID一>规则.您声明 Car::setEngine 接受一个 Engine 类型的参数,但是子 WaterCar::setEngine 接受一个 类型的参数水力发动机.即使 HydroEngineEngine 的子类型,它仍然是不同的类型.

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实现了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.子类与父类完全相同,并且可能更多.它不能比父级.由于HydroEngineEngine 的一个特殊子类型,这意味着WaterCarCar,因为它只接受更窄的 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.

这篇关于使用子接口作为新参数覆盖方法参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆