51

我已经建立了一个抽象父类和一个扩展它的具体类。为什么父类不能调用抽象函数?

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

4

3 回答 3

86

这是一个正确的实现;您应该使用静态而不是自我,以便使用后期静态绑定

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

给出预期的“bar”。

请注意,这并不是真正的多态性。静态键只是解析到调用静态方法的类中。如果你声明一个抽象静态方法,你会收到一个严格的警告。如果子(子)类中不存在它们,PHP 只会从父(超)类复制所有静态方法。

于 2010-05-18T17:56:42.503 回答
8

你注意到那个词了self吗?

那是指向AbstractClass。因此它调用的是 AbstractClass::foo(),而不是 ConcreteClass::foo();

我相信 PHP 5.3 会提供后期静态绑定,但如果你不在那个版本上,self 将不会引用扩展类,而是函数所在的类。

见:http ://us.php.net/manual/en/function.get-called-class.php

于 2010-05-18T17:55:41.850 回答
0

这是一个规则,abstract关键字static不能同时用于一个方法。

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

所以这就是错误发生的原因。

于 2012-02-17T16:12:38.933 回答