我知道有几个类似的问题在这里StackOverflow上像这样的问题 。
为什么覆盖方法参数违反了在PHP严格的标准? 例如:
class Foo
{
public function bar(Array $bar){}
}
class Baz extends Foo
{
public function bar($bar) {}
}
严格的标准:巴兹::巴的声明()应该与富::酒吧兼容()
在其他OOP编程语言即可。 为什么是坏在PHP?
我知道有几个类似的问题在这里StackOverflow上像这样的问题 。
为什么覆盖方法参数违反了在PHP严格的标准? 例如:
class Foo
{
public function bar(Array $bar){}
}
class Baz extends Foo
{
public function bar($bar) {}
}
严格的标准:巴兹::巴的声明()应该与富::酒吧兼容()
在其他OOP编程语言即可。 为什么是坏在PHP?
在OOP, SOLID代表单一职责,开闭,Liskov替换,接口分离和依赖反转 。
Liskov替换原则指出的是,在一个计算机程序中,如果酒吧是富的子类型,则Foo类型的对象可以与类型栏的对象,而不改变任何节目的期望的性质(正确性,执行任务等的取代)。
在强类型的编程语言,覆盖一个Foo方法时,如果你在酒吧更改签名,你实际上是超载 ,因为原来的方法和新的方法都可以用不同的签名。 由于PHP是弱类型化的,这是不可能实现的,因为编译器无法知道其中的方法,你实际上是调用。 (因此原因,你不能有2种方法具有相同的名字,即使他们的签名是不同的)。
因此,为了避免违反Liskov的Substituition原则,严格把关发出警告,告诉程序员的东西,由于在子类中的方法签名的变化有可能打破。
I know I am late to the party but the answers don't really spell out the actual problem.
The problem is PHP doesn't support function/method overloading. It would be difficult to support function overloading in an untyped language.
Hinting helps. but in PHP it is very limited. Not sure why. For example you cannot hint a variable is an int or Boolean yet array is fine. Go figure!
Other object orientated languages implement this using function overloading. Which is to say the signature of the function is obviously different.
So for example if the following was possible we would not have an issue
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
Of course when it came to constructors the php developers realised they have to implement it, Like it or not! So they simply suppress the error or not raise it in the first case.
Which is silly.
An acquaintance once said PHP implemented objects only as a way of implementing namespaces. Now I am not quite that critical but some of the decisions taken do tend to support that theory.
I always have maximum warnings turned on when developing code, I never let a warning go by without understanding what it means and what the implications are. Personally I don't care for this warning. I know what I want to do and PHP doesn't do it right. I came here looking for a way to selectively suppress it. I haven't found a way yet.
So I will trap this warning and suppress it myself. Shame I need to do this. but I am strict about STRICT.
您可以覆盖参数,但签名应该匹配。 如果你已经把Array
出门前$bar
,不会有什么问题。
举例来说,如果你加入了一个额外的参数,不会有什么问题,只要第一个参数有相同类型提示。 这是在任何语言中好的做法。
因为你在宣布Foo
是$bar
应该是类型的array
,而在扩展Bar
, $bar
的类型不声明。
这是不是一个错误,这是一个警告。 你应该做的方法定义与原始,基类兼容。 你可以,但是,忽略它,如果你知道自己在做什么(且仅当你知道你在做什么!)