14

我不明白我做错了什么......

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...
    }
}

它给了我:

[2013 年 7 月 8 日星期一 13:21:10] PHP 致命错误:无法在第 21 行的 /home/arthur/NetBeansProjects/capa/CssElem.php 中继承抽象函数 Css::parse()(之前在 CssElem 中声明的抽象) [2013 年 7 月 8 日星期一 13:21:10] 127.0.0.1:41207 [500]: / - 无法在 /home/arthur/NetBeansProjects/capa 中继承抽象函数 Css::parse()(之前在 CssElem 中声明的抽象) /CssElem.php 第 21 行

第 21abstract protected function parse($data);行在 CssElem 中。

我更熟悉Java中的OOP,但根据文档似乎还可以......

4

4 回答 4

16

尝试将您的中级课程更改为:

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

于 2013-07-08T11:38:51.707 回答
12

Patrick Huy 的回答绝对有帮助。

此处记录了此错误:
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::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) {}
}
于 2014-03-20T00:40:05.147 回答
3

我最近也遇到了这个问题。对我来说,它有助于从 PHP 5.3.8 升级到 PHP 5.3.28。

我不知道更改发生的确切时间,但在 5.3.28 中,可以在抽象类中重新声明接口方法并仍然从它们继承。

于 2014-01-27T12:57:13.887 回答
2

您不需要再次重新声明您的抽象函数,只需在实现时声明即可。

当您在 CssElem 上扩展 Css 时,函数 parse 就组合在一起了。当你实现 CssElem 时,你也应该实现 parse 函数。

于 2013-07-08T11:40:03.007 回答