我知道StackOverflow中有类似问题,就像这个问题一样.
为什么重写方法参数违反了PHP中的严格标准?例如:
class Foo
{
public function bar(Array $bar){}
}
class Baz extends Foo
{
public function bar($bar) {}
}
Run Code Online (Sandbox Code Playgroud)
严格的标准:Baz :: bar()的声明应该与Foo :: bar()的声明兼容
在其他OOP编程语言中,您可以.为什么PHP不好?
Tiv*_*vie 51
在OOP中,SOLID代表单一责任,开放式封闭,Liskov替换,接口隔离和依赖性反转.
Liskov替换原则指出的是,在一个计算机程序中,如果酒吧是的子类型的Foo,然后类型的对象的Foo可以与类型的对象替换酒吧而不改变任何节目的期望的性质(正确性,执行任务等的).
在强类型编程语言中,当覆盖Foo方法时,如果更改Bar中的签名,则实际上是在重载,因为原始方法和新方法可用于不同的签名.由于PHP是弱类型的,因此无法实现,因为编译器无法知道您实际调用的是哪种方法.(因此,即使他们的签名不同,您也不能拥有2个具有相同名称的方法).
因此,为了避免违反Liskov Substituition原则,会发出严格的标准警告,告诉程序员由于子类中方法签名的更改而可能会出现问题.
Dev*_*ris 18
我知道我迟到了,但答案并没有真正说明实际问题.
问题是PHP不支持函数/方法重载.在无类型语言中支持函数重载是很困难的.
提示有帮助.但在PHP中它非常有限.不知道为什么.例如,您不能提示变量是int或Boolean但数组是正常的.去搞清楚!
其他面向对象的语言使用函数重载来实现这一点.也就是说功能的签名明显不同.
因此,例如,如果以下可能,我们就不会有问题
class Foo
{
public function bar(Array $bar){
echo "Foo::bar";
}
}
class Baz extends Foo
{
public function bar(int $bar) {
echo "Baz::bar";
}
}
$foo = new Baz();
$bar = new Baz();
$ar = array();
$i = 100;
$foo->bar($ar);
$bar->bar((int)$i);
would output
Foo::bar
Baz::bar
Run Code Online (Sandbox Code Playgroud)
当然,当涉及构造函数时,php开发人员意识到他们必须实现它,无论喜欢与否!因此,他们只是在第一种情况下抑制错误或不提高错误.
哪个很傻.
熟人曾经说PHP实现的对象只是一种实现名称空间的方式.现在我并不是那么重要,但是所做的一些决定确实倾向于支持这一理论.
在开发代码时我始终会打开最大警告,我从不会在不了解其含义和含义的情况下发出警告.我个人不关心这个警告.我知道自己想做什么,而PHP却做得不对.我来到这里寻找一种有选择地抑制它的方法.我还没有找到办法.
所以我会抓住这个警告并自己压制它.惭愧我需要这样做.但我对STRICT很严格.