PHP>;5.4:使用不同签名覆盖构造函数
我们知道PHP不接受带有。我认为构造器也是如此:PHP文档 这也适用于PHP5.4中的构造函数。在5.4之前,构造函数签名可能会有所不同 但是,继承的构造函数在PHP版本>5.4中仍然可能有所不同。例如,以下代码不会触发任何警告或通知:PHP>;5.4:使用不同签名覆盖构造函数,php,oop,constructor,Php,Oop,Constructor,我们知道PHP不接受带有。我认为构造器也是如此:PHP文档 这也适用于PHP5.4中的构造函数。在5.4之前,构造函数签名可能会有所不同 但是,继承的构造函数在PHP版本>5.4中仍然可能有所不同。例如,以下代码不会触发任何警告或通知: class Something { } class SomeOtherThing { } class Foo { public function __construct(Something $foo) { } public f
class Something { }
class SomeOtherThing { }
class Foo
{
public function __construct(Something $foo)
{
}
public function yay()
{
echo 'yay';
}
}
class Bar extends Foo
{
public function __construct($foo, SomeOtherThing $bar = null)
{
}
}
$x = new Bar(new Something());
$x->yay();
根据文档,代码应该触发错误,因为构造函数签名不同
在PHP5.6.4上尝试过这个。效果与此相同
那么,这是怎么回事?不管文档上怎么说,不同的构造函数签名仍然合法吗?或者这是一个将在以后版本中修复的错误?我认为您对文档有点误读,因为它指出: 此外,方法的签名必须匹配,即类型 提示和所需参数的数量必须相同。对于 例如,如果子类定义了可选参数,则 抽象方法的签名不存在冲突,在 签名 您已经定义了一个可选参数,因此它是可以的。根据 与其他方法不同,当使用不同于父_construct()方法的参数重写_construct()时,PHP不会生成E_严格级别的错误消息
因此,这就是为什么您没有得到E_STRICT级别的错误。也许它会在另一个层面上触发一些东西。这与抽象方法有关,而不是具体的方法implementations@zerkms-这是一种允许您定义签名的机制,与接口定义签名
抽象公共函数\uuuu构造(某物$foo)的方式完全相同代码>然后在扩展抽象的类中强制该签名。。。。。这样做可能不是明智的做法,但OP链接到的文档页面就是这么说的about@MarkBaker这是胡说八道:构造函数不是接口的一部分,也不能是多态的。约束构造函数参数是愚蠢的。我几乎不相信php团队能做到这点。@zerkms,php从来没有被标记为完美的语言。它有它的缺陷(事实上有很多)。@zerkms:我同意,但是为什么PHP文档声明继承的构造函数不能与父构造函数不同呢?这才是真正的问题,不。第一个参数要求父类中有Something
的实例,而子类中没有这样的要求。如果这是一个普通的方法,而不是一个构造函数,它将导致错误:而且,顺便说一句,如果第二个参数在我的示例中不是可选的,它仍然可以工作:嗯,也不是真正令人满意的,但至少它看起来是记录在案的/预期的行为。顺便说一句,正如我提到的,它甚至不会触发E_NOTICE
或E_STRICT
。注意,文档说抽象类签名必须匹配。问题中提供的类不是抽象类。