Почему вы не можете вызывать абстрактные функции из абстрактных классов в PHP? - PullRequest
37 голосов
/ 18 мая 2010

Я установил абстрактный родительский класс и конкретный класс, который расширяет его. Почему родительский класс не может вызывать абстрактную функцию?

//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 () в foo.php в строке 5

Ответы [ 3 ]

63 голосов
/ 18 мая 2010

Это правильная реализация; вы должны использовать 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 просто копирует все статические методы из родительского (супер) класса, если они не существуют в дочернем (под) классе.

7 голосов
/ 18 мая 2010

Вы замечаете это слово self?

Это указывает на AbstractClass. Таким образом, он вызывает AbstractClass :: foo (), а не ConcreteClass :: foo ();

Я считаю, что PHP 5.3 обеспечит поздние статические привязки, но если вы не используете эту версию, self не будет ссылаться на расширенный класс, а на класс, в котором находится функция.

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

0 голосов
/ 17 февраля 2012

Как правило, ключевые слова abstract и static нельзя использовать в методе одновременно.

Метод с ключевым словом abstract означает, что подкласс должен его реализовать. Добавление статического метода в метод класса позволяет нам использовать метод без его создания.

Так вот почему возникает ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...