正确覆盖的PHP方法是什么?
php -a
Interactive mode enabled
php > error_reporting(E_ALL);
php > class A { public function z($a, $b){} }
php > class B extends A { public function z($a){parent::z($a, '1');} }
PHP Strict standards: Declaration of B::z() should be compatible with A::z($a, $b) in php shell code on line 1
注意:覆盖是英文中的正确单词吗?
答案 0 :(得分:2)
在您的示例中,class A
函数z
中有2个参数,在class B
中您尝试使用1个参数声明它。在PHP中它不会工作。
顺便说一下。我猜你可能想要超载funciotn z
而不是覆盖它,而且它在php中并不真正支持。如果我就在这里,对手册的解释很少:
注意:
PHP对“重载”的解释与大多数面向对象的语言不同。传统上,重载提供了具有相同名称但不同数量和类型的参数的多个方法的能力。
答案 1 :(得分:1)
E_STRICT通知的原因(这只是一个编程提示,而不是错误本身)是一个子类理论上应该可以与其父类互换使用(豪华术语是“Liskov替换原则”)。 / p>
在您的情况下,您需要知道您拥有B
的实例才能省略第二个参数。 PHP正在放松并允许你这样做,但实际上并不是继承应该如何工作 - B extends A
应该意味着所有“B
”也是“A
”。 / p>
如果您使用interface
来定义function z($a, $b)
的合同,则类B
会违反该合同。
解决此问题的更好方法是使用委派而不是继承:class B
可以充当使用{{1}的“适配器”行为,但简化了它,例如
A
在这里,我们没有承诺调用有关class B
{
private $delegated_a;
public function __construct() {
$this->delegated_a = new A;
}
public function z($a) {
$this->delegated_a->z($a, '1');
}
}
和A
之间关系的代码,因此可以重新定义我们喜欢的方法。
答案 2 :(得分:0)
你的意思是方法重载:)
实际上,如果您之前使用Java编程,那么它的工作方式会有所不同。另请查看PHP manual中的评论。
区别在于例如。 Java可以有多个具有相同名称但另一个足迹的方法。例如:
public void max(int a, int b) {
// calculate max value
}
public void max(double a, double b, double c) {
// do some other calculation
}
现在,如果您调用方法max,Java将自动决定使用哪种方法。
现在在PHP中这不起作用。您可以覆盖子类中的方法,但仅限于脚印相同,并且您只能在子类中定义方法。例如:
class A {
function z($a, $b) {
echo 'called in A';
}
}
class B extends A {
function z($a, $b) {
echo 'called in B';
}
}
$a = new A;
$b = new B;
$a->z(1, 2); // prints out "called in A"
$b->z(1, 2); // prints out "called in B"