2010-05-18 1 views
27

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

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

Ошибка:

Fatal error: Cannot call abstract method AbstractFoo::foo() in foo.php on line 5

+3

LOL ... static abstract ...: D: cool question – Simon

ответ

48

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

+2

Sick ... Спасибо! В чем разница между собой и статикой? Изменить: По-видимому, это ключевое слово не существует (возможно, это версия). – Cam

+2

Прочитайте страницу руководства по поздним статическим связям, которые я связал. – Artefacto

+1

Да, это доступно только на PHP 5.3. – Artefacto

7

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

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

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

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

+0

Ключевое слово вместо 'self' для использования -' static' для ссылки 'ConcreteClass' в 5.3+ – philfreo

0

Это правило, что abstract и static ключевые слова не могут быть использованы при одновременном использовании метода.

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

Таким образом, возникает ошибка.

+0

не ясный ответ !! – Deepak

+0

И, тем не менее, их можно использовать. Примером может быть использование статического setUpBeforeClass() PHPUnit со значениями, зависящими от подклассов, - вам понадобится абстрактный (так что подклассы реализуют его в первую очередь, а также по-разному), статический (так что вы можете вызвать его из метода setUpBeforeClass()). – Buffalo

 Смежные вопросы

  • Нет связанных вопросов^_^