我已经设置了一个抽象的父类,以及一个扩展它的具体类。为什么父类不能调用抽象函数?
//foo.php
<?php
abstract class AbstractFoo{
abstract public static function foo();
public static function getFoo(){
return self::foo();//line 5
}
}
class ConcreteFoo extends AbstractFoo{
public static function foo(){
return "bar";
}
}
echo ConcreteFoo::getFoo();
?>
错误:
致命错误:无法在第5行的 foo.php 中调用抽象方法AbstractFoo :: foo()
答案 0 :(得分:63)
这是一个正确的实施;你应该使用静态而不是自我来使用late static bindings:
abstract class AbstractFoo{
public static function foo() {
throw new RuntimeException("Unimplemented");
}
public static function getFoo(){
return static::foo();
}
}
class ConcreteFoo extends AbstractFoo{
public static function foo(){
return "bar";
}
}
echo ConcreteFoo::getFoo();
给出了预期的“条形”。
请注意,这不是真正的多态性。静态键工作只是解析为调用静态方法的类。如果声明一个抽象静态方法,您将收到严格警告。 PHP只是复制父(超)类中的所有静态方法,如果它们在子(子)类中不存在。
答案 1 :(得分:7)
你注意到这个词self
?
指向AbstractClass。因此它调用AbstractClass :: foo(),而不是ConcreteClass :: foo();
我相信PHP 5.3将提供后期静态绑定,但如果你不在那个版本上,self将不会引用扩展类,而是引用该函数所在的类。
请参阅:http://us.php.net/manual/en/function.get-called-class.php
答案 2 :(得分:0)
规则abstract
和static
关键字不能同时用于某个方法。
带有abstract
关键字的方法意味着子类必须实现它。将static添加到类的方法允许我们在不实例化的情况下使用该方法。
这就是错误发生的原因。