关于liskov替换原则:Specific :: method()的声明:必须与General :: method()兼容。

Declaration of Specific::method(): must be compatible with General::method(). Is PHP wrong about LSP?

我猜"…必须与……兼容,以执行Liskov替换原则。但我不确定这就是LSP说的?

我有这样的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class General
{
    public static function create(): General
    {
        return new static;
    }

    public function doSomething()
    {
        echo get_class($this) . ' speaking!' . PHP_EOL;
    }
}


class Specific extends General
{
    public static function create(): Specific
    {
        return parent::create();
    }
}


function doSomething(General $object)
{
    $object->doSomething();
}

doSomething(General::create());
doSomething(Specific::create());

产生:

PHP Fatal error: Declaration of Specific::create(): Specific must be compatible with General::create(): General in ...

LSP通常被引用为:

Functions that use pointers or references to base classes must be able
to use objects of derived classes without knowing it.

据我所知,这并没有违反。那么这里怎么了?是否有与LSP无关的特殊限制?这是PHP中的错误吗?我不知道自己做错了什么吗?

更新:我发现了这个线程(专用化中的参数类型协方差)。我理解并完全同意这里的例子违反了LSP。但我的情况不同(事实相反)。


http://net/手册/恩/ functions.returning-values.php

When overriding a parent method, the child's method must match any return type declaration on the parent. If the parent doesn't define a return type, then the child method may do so.

你应该用一GeneralSpecific::create函数返回类型。

否则,代码写的很Specific::create日休息时运行General::create,它会接收一个不同的类。