为后代类键入提示

时间:2015-01-29 14:57:49

标签: php type-hinting

来自文档页面http://php.net/manual/en/language.oop5.typehinting.php

如果将类或接口指定为类型提示,则也允许其所有子项或实现。

可是:

class PimpleChild extends Pimple {
//...
}
interface Pimple_Config {
    public function configure(Pimple $container);
}
class PimpleConfigurer_Factories implements Pimple_Config {
    public function configure(PimpleChild $container) {
    //...
    }
}

返回致命错误。为什么呢?

2 个答案:

答案 0 :(得分:4)

如果我没弄错,你会收到这个错误:

Declaration of PimpleConfigurer_Factories::configure() must be compatible with Pimple_Config::configure(Pimple $container) ...

这意味着:如果在超类或接口中定义方法,则所有子类(或实现接口的类)必须使用此定义。你不能在这里使用其他类型。

至于您在文档中的引用:

  

如果将类或接口指定为类型提示,则也允许其所有子项或实现。

这仅表示您可以传递某种类型的变量或其所有子项。

例如:假设您有以下类:

class Car {
    protected $hp = 50;
    public function getHp() { return $this->hp; }
}

class SuperCar extends Car {
    protected $hp = 700;
}

一个带有类型提示的函数(或方法,没有区别):

function showHorsePower(Car $car) {
    echo $car->getHp();
}

现在,您可以将Car类型及其所有子类(此处为SuperCar)的所有对象传递给此函数,例如:

showHorsePower(new Car());
showHorsePower(new SuperCar());

答案 1 :(得分:3)

来自同一个typehinting section you linked to

  

实现接口的类必须使用与接口中定义的完全相同的方法签名。不这样做会导致致命错误。

要使方法签名相同,它们必须包含完全相同的类型提示。而且因为它很相似......

从手册的OOP Basics - extends部分:

  

覆盖方法时,参数签名应保持不变,否则PHP将生成E_STRICT级错误。这不适用于构造函数,它允许覆盖不同的参数。