为什么不能在PHP中从抽象类调用抽象函数?

时间:2010-05-18 17:42:22

标签: php oop static methods abstract

我已经设置了一个抽象的父类,以及一个扩展它的具体类。为什么父类不能调用抽象函数?

//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()

3 个答案:

答案 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)

规则abstractstatic关键字不能同时用于某个方法。

带有abstract关键字的方法意味着子类必须实现它。将static添加到类的方法允许我们在不实例化的情况下使用该方法。

这就是错误发生的原因。