Я настроил абстрактный родительский класс и реальный класс, который расширяет его. Почему родительский класс не может вызвать абстрактную функцию?
//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();
?>
Ошибка:
Фатальная ошибка: не Может назвать абстрактный метод AbstractFoo:: нечто () в foo.php на строке 5
Это правильная реализация; вы должны использовать static, а не self, чтобы использовать поздние статические привязки :
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 просто копирует все статические методы из родительского (суперкласса), если они не существуют в дочернем (подклассе).
Вы заметили слово self
?
Это указывает на AbstractClass. Таким образом, он вызывает AbstractClass :: foo (), а не ConcreteClass :: foo ();
Я считаю, что PHP 5.3 обеспечит поздние статические привязки, но если вы не используете эту версию, self не будет ссылаться на расширенный класс, но класс, в котором находится функция.
См .: http://us.php.net/manual/en/function.get-called-class.php