为什么重写方法参数违反了PHP中的严格标准?
我知道在这个问题 StackOverflow中有几个类似的问题 。
为什么重写方法参数违反了PHP中的严格标准? 例如:
class Foo { public function bar(Array $bar){} } class Baz extends Foo { public function bar($bar) {} }
严格的标准:Baz :: bar()声明应该与Foo :: bar()的兼容
在其他的OOP编程语言中,你可以。 为什么在PHP中不好?
在OOP中, SOLID代表单一责任,开放式,Liskov替代,界面隔离和依赖倒置 。
Liskov替代原则规定,在计算机程序中,如果Bar是Foo的子types,那么Footypes的对象可以用Bartypes的对象replace而不改变该程序的任何期望属性(正确性,执行的任务等)。 )。
在强types编程语言中,当重写Foo方法时,如果在Bar中更改签名,则实际上会重载,因为原始方法和新方法可用于不同的签名。 由于PHP是弱types的,这是不可能实现的,因为编译器不能知道你实际调用了哪些方法。 (因此,即使签名不同,也不能有两个同名的方法)。
因此,为了避免违反Liskov替代原则,会发出一个严格的标准警告,告诉程序员可能由于子类中的方法签名的改变而破坏。
我知道我晚了,但答案并没有真正解决实际问题。
问题是PHP不支持函数/方法重载。 用无types的语言来支持函数重载是很困难的。
暗示帮助。 但在PHP中是非常有限的。 不知道为什么。 例如,你不能提示一个variables是一个int或布尔值,但数组很好。 去搞清楚!
其他面向对象的语言使用函数重载来实现这一点。 也就是说function的签名明显不同。
所以例如,如果以下是可能的,我们不会有问题
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
当然,当涉及到构造函数时,PHP开发人员意识到他们必须实现它,喜欢还是不喜欢! 所以他们只是在第一种情况下抑制错误或者不提高。
这是愚蠢的。
一位熟人曾经说过,PHP实现的对象只是实现名称空间的一种方式。 现在我不是那么批评,但是一些做出的决定倾向于支持这个理论。
在开发代码时,我总是会打开最大的警告,如果不明白它的含义和含义,我绝不会让警告过去。 我个人不关心这个警告。 我知道我想做什么,PHP不正确。 我来到这里寻找一种方法来有select地压制它。 我还没有find方法。
所以我会陷入这个警告并且自己压制它。 耻辱我需要这样做。 但我严格严格。
您可以覆盖参数,但签名应该匹配。 如果你把Array
放在$bar
前面,那就没有问题了。
例如,如果您添加了一个附加参数,则不会有任何问题,只要第一个参数具有相同types的提示即可。 这是任何语言的良好习惯。
因为你在Foo
声明$bar
应该是array
types,而在扩展Bar
, $bar
的types没有被声明。
这不是一个错误,这是一个警告。 您应该使方法定义与原始基类兼容。 但是,如果你知道自己在做什么( 只有当你知道自己在做什么的时候), 才能安全地忽略它。