PHP致命错误:无法继承抽象函数

Art*_*hur 13 php oop abstract-class

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

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...
    }
}
Run Code Online (Sandbox Code Playgroud)

它给了我:

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

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

我对Java中的OOP比较熟悉,但根据文档似乎没问题......

Mat*_*ari 16

尝试将您的中间类更改为:

abstract class CssElem extends Css {
    // abstract protected function parse($data); // <-- take this away
}
Run Code Online (Sandbox Code Playgroud)

另请参阅文档中的此评论.

引用评论:

在实现其父抽象类的抽象方法时,扩展抽象类的抽象类可以将buck传递给它的子类.

但是,似乎在下一个PHP版本7.2中允许这样做:

现在允许在子类中使用另一个抽象方法覆盖抽象方法.(https://wiki.php.net/rfc/allow-abstract-function-override)


don*_*ote 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();
}
Run Code Online (Sandbox Code Playgroud)

添加了可选参数

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);
}
Run Code Online (Sandbox Code Playgroud)

添加所需参数

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);
}
Run Code Online (Sandbox Code Playgroud)

(我们并不感到惊讶,这在所有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) {}
}
Run Code Online (Sandbox Code Playgroud)