2014-03-05 48 views
1

什么是PHP方法来做一个正确的覆盖?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

是的,在这种情况下,覆盖是正确的。然而,_Work_不是。 – Cthulhu

回答

1

的原因E_STRICT通知(这仅仅是一个编程提示,而不是错误本身)是一个子类理论上应该是与其父可互换使用(豪华的术语是“里氏替代原则“)。

在你的情况下,你需要知道知道,你有一个B的实例,以避开第二个参数。 PHP正在放松,让你这样做,但它不是如何继承应该如何工作 - B extends A应该意味着“是B”也是“A”。

如果您使用interface来定义function z($a, $b)的合同,那么类B将违反该合同。

此问题的一个更好的办法是使用代表团而不是继承:类B可以作为利用A的行为的“适配器”行动,但它简化,例如

class B 
{ 
    private $delegated_a; 

    public function __construct() { 
     $this->delegated_a = new A; 
    } 

    public function z($a) { 
     $this->delegated_a->z($a, '1'); 
    } 
} 

在这里,我们正在做没有承诺,呼吁有关AB之间的关系码,所以可以重新定义但我们喜欢的方式。

+0

s /'A继承B' /'B extends A'/ – cHao

+0

@cHao好点。固定。 – IMSoP

+0

需要交换'A'和'B',因为'B'代表别处的子类。否则,你的陈述就相当于“狗延伸哺乳动物”应该意味着'是'哺乳动物'也是'狗'“。 – cHao

2

在你的榜样,在class A功能z有2个参数,class B你试图用1个参数来声明。在PHP中它不会工作。

Btw。我想你可能想要overover funciotn z不会覆盖它,它并不真正支持在PHP中。如果我在这里是有点解释来回手册:

注:“超载”的

PHP的解释是比大多数面向对象的语言不同。重载传统上提供了具有相同名称但不同数量和类型参数的多个方法的能力。

+2

除了触发E_STRICT通知和fl光LSP之外,它在我的经验中工作得很好。 (这两者几乎肯定是相关的。) – cHao

+1

相同运算符可以采用不同数量/类型的参数(因此具有不同的行为)的语言不是_overload_吗?什么孩子类在PHP中确实_overrides_它是父母的方法/属性。 – Cthulhu

+0

@Cthulhu在这个例子中,它实际上是这样做的:它重写*父类方法,但是改变参数的数量,在某些语言中这意味着它*重载*该方法... – IMSoP

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" 
+0

如果你看看你链接的那个页面,你会发现在PHP中,“超载”特别指的是使用魔术方法。 – cHao

+1

我认为你的意思是“指纹”,或者更常见的是“签名”,而不是“足迹”。 – IMSoP

+0

@cHao,这就是为什么我说它有点不同,有点轻描淡写的感觉;)IMSoP:你说得对! – giorgio