PHP Неустранимая ошибка: не удается наследовать абстрактную функцию
Я не понимаю, что я делаю неправильно...
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 [Пн Июл 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, но он выглядит нормально в соответствии с документом...
Ответы
Ответ 1
Попробуйте изменить свой промежуточный класс на:
abstract class CssElem extends Css {
// abstract protected function parse($data); // <-- take this away
}
См. также этот комментарий в документах.
Цитата из комментария:
Абстрактный класс, который расширяет абстрактный класс, может передавать доллар его дочерние классы, когда дело доходит до реализации абстрактных методов его родительского абстрактного класса.
Кажется, что это будет разрешено в следующем PHP версии 7.2:
Теперь разрешено переопределять абстрактный метод другим абстрактным методом в дочернем классе. (https://wiki.php.net/rfc/allow-abstract-function-override)
Ответ 2
Ответ Патрика Хай был определенно полезен.
Эта ошибка описана здесь:
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) {}
}
Ответ 3
Недавно я столкнулся с этой проблемой. Для меня это помогло перейти с PHP 5.3.8 на PHP 5.3.28.
Я не знаю точно, когда произошло изменение, но в 5.3.28 можно переопределить методы интерфейса в абстрактных классах и по-прежнему унаследовать их.
Ответ 4
Вам не нужно снова объявлять свою абстрактную функцию, объявляйте только о ее реализации.
Когда вы расширяете Css на CssElem, функция parse объединяется. Когда вы реализуете CssElem, вы должны также реализовать функцию синтаксического анализа.