Я не понимаю, что я делаю неправильно …
abstract class Css { abstract protected function parse($data); } abstract class CssElem extends Css { abstract protected function parse($data); } class Modifier extends CssElem { function __construct($data = null) { if( $data ) $this->parse ($data); } protected function parse($data) { // Some code... } }
Это дает мне:
[Mon Jul 8 13:21:10 2013] PHP Неустранимая ошибка: не удается наследовать абстрактную функцию Css :: parse () (ранее объявленный реферат в CssElem) в /home/arthur/NetBeansProjects/capa/CssElem.php в строке 21 [Mon Jul 8 13:21:10 2013] 127.0.0.1:41207 [500]: / – Невозможно наследовать абстрактную функцию Css :: parse () (ранее объявленный реферат в CssElem) в / home / arthur / NetBeansProjects / capa /CssElem.php в строке 21
Строка 21 – abstract protected function parse($data);
в CssElem.
Я больше знаком с ООП в Java, но, похоже, в соответствии с документом …
Попробуйте изменить свой средний класс на:
abstract class CssElem extends Css { // abstract protected function parse($data); // <-- take this away }
См. Также этот комментарий в документах.
Цитата из комментария:
Абстрактный класс, который расширяет абстрактный класс, может передать buck его дочерним классам, когда речь заходит о реализации абстрактных методов родительского абстрактного класса.
Кажется, однако, что это будет разрешено в следующей версии PHP 7.2 :
Теперь разрешено переопределять абстрактный метод с другим абстрактным методом в дочернем классе. ( https://wiki.php.net/rfc/allow-abstract-function-override )
Ответ Патрика Хай был определенно полезен.
Эта ошибка описана здесь:
https://bugs.php.net/bug.php?id=43200
Как отмечено там, ошибка имеет значение, если вы хотите расширить устаревшие интерфейсы.
Его можно воспроизвести на http://3v4l.org , показывая, что он исправлен с PHP 5.3.9.
Это может быть «исправлено» решением Matteo Tassinari, комментируя определение foo () во втором интерфейсе.
http://3v4l.org/qo6sG
5.0.0 – 5.3.8: Неустранимая ошибка: не удается наследовать абстрактную функцию A :: foo ()
5.3.9 – *: Нет проблем.
interface A { function foo(); } interface B extends A { function foo(); }
http://3v4l.org/ZXq0O
5.0.0 – 5.3.8: Неустранимая ошибка: не удается наследовать абстрактную функцию A :: foo ()
5.3.9 – *: Нет проблем.
interface A { function foo(); } interface B extends A { function foo($x = NULL); }
http://3v4l.org/5fPBO
5.0.0 – 5.3.8: Неустранимая ошибка: не удается наследовать абстрактную функцию A :: foo ()
5.3.9 – *: Неустранимая ошибка: Декларация B :: foo () должна быть совместима с (A) A :: foo ()
interface A { function foo(); } interface B extends A { function foo($x); }
(Мы не удивлены, это ломается во всех версиях PHP)
http://3v4l.org/UvcLA
5.0.0 – *: Нет проблем
/** * @legacy */ interface A { function foo(); } /** * Supersedes legacy interface A */ interface B extends A { /** * @param int|null $x * Optional parameter added in new version. */ # function foo($x = NULL); } class C implements B { function foo($x = NULL) {} }
Я недавно столкнулся с этой проблемой. Для меня это помогло перейти с PHP 5.3.8 на PHP 5.3.28.
Я не знаю точно, когда произошло изменение, но в 5.3.28 можно переопределить методы интерфейса в абстрактных классах и по-прежнему унаследовать их.
Вам не нужно снова объявлять свою абстрактную функцию, объявляйте только о ее реализации.
Когда вы расширяете Css на CssElem, синтаксический анализ функции объединяется. Когда вы реализуете CssElem, вы должны также реализовать функцию синтаксического анализа.