我认为php的面向对象编程实现存在问题。
编辑:考虑一个更具有说明性的例子:
abstract class Animal {
public $name;
// public function Communicate(Animal $partner) {} // Works
public abstract function Communicate(Animal $partner); // Gives error
}
class Panda extends Animal {
public function Communicate(Panda $partner) {
echo "Hi {$partner->name} I'm a Panda";
}
}
class Human extends Animal {
public function Communicate(Human $partner) {
echo "Hi {$partner->name} I'm a Human";
}
}
$john = new Human(); $john->name = 'John';
$mary = new Human(); $mary->name = 'Mary';
$john->Communicate($mary); // should be ok
$zuzi = new Panda(); $zuzi->name = 'Zuzi';
$zuzi->Communicate($john); // should give error
问题在于当Animal::Communicate是一个抽象方法时,PHP会提示以下方法是非法的:
"public function Communicate(Panda $partner)" "public function Communicate(Human $partner)"
但是当Animal::Communicate不是抽象方法,而是具有零实现时,PHP认为这些方法是合法的。因此,在我看来,这并不正确,因为我们在两种情况下都进行了重写,并且这两种情况是相等的,所以这似乎是一个bug...
请考虑以下代码:
Framework.php
namespace A
{
class Component { ... }
abstract class Decorator {
public abstract function Decorate(\A\Component $component);
}
}
Implementation.php
namespace B
{
class MyComponent extends \A\Component { ... }
}
MyDecorator.php
namespace A
{
class MyDecorator extends Decorator {
public function Decorate(\B\MyComponent $component) { ... }
}
}
以下代码在MyDecorator.php中出现错误,提示:
致命错误:MyDecorator :: Decorate()的声明必须与A \ Decorator :: Decorate()兼容,在MyDecorator.php的第...行
但是,当我将Framework.php :: Decorator类更改为以下实现时:
abstract class Decorator {
public function Decorate(\A\Component $component) {}
}
问题消失了。
\A\Component
参数的函数,而你的实现只接受\B\MyComponent
。这意味着你没有实现超类所“要求”的函数。 - Nanne