在 PHP7 中,为什么子类的方法可以定义返回类型,而重写的父类方法却不能?

Cra*_*ton 1 php inheritance

考虑以下代码片段:

class Foo
{
    public function fooMethod()
    {
        return [];
    }
}

class Bar extends Foo
{
    public function fooMethod(): array
    {
        return ['something'];
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以正常工作,没有任何错误(在 PHP7.4 和 PHP7.3 中测试)。为什么 PHP 不强制子级的方法签名与父级相同(即没有返回类型)?PHP 允许这样做是否有正当理由,或者这是一个错误?我的猜测是,通过不在父级中声明它,我们本质上是说它可以返回“混合”,因此任何返回类型都是有效的,但我很想知道原因。

Mar*_*tin 5

PHP手册指出:

笔记:

当重写父方法时,子方法必须与父方法上的任何返回类型声明相匹配。如果父方法没有定义返回类型,则子方法可能会这样做。

请注意这一行:“如果父方法没有定义返回类型,则子方法可能会这样做”

所以如果你看看你的例子;Foo 类中的父方法没有定义返回类型,因此 Bar 类中的子方法可以设置它希望的任何返回类型。


A:

class Foo
{
    public function fooMethod()
    {
        return []; // returns an array. Type expected: any.
    }
}

class Bar extends Foo
{
    public function fooMethod(): array
    {
        return ['something']; // returns an array, type expected: array
    }
}
Run Code Online (Sandbox Code Playgroud)

乙:

这个工作正常,因为没有预先存在的类型期望,因此当子类设置类型时,它不会覆盖任何内容。

class Foo
{
    public function fooMethod()
    {
        return []; // returns an array, type expected any
    }
}

class Bar extends Foo
{
    public function fooMethod(): string
    {
        return "horses"; // returns a string, type expected: string
    }
}
Run Code Online (Sandbox Code Playgroud)

C:

这会导致问题(即,你邪恶的军事月球基地将因失去所有双手而被摧毁),因为子方法试图覆盖父方法已定义的返回类型属性。

class Foo
{
    public function fooMethod(): int
    {
        return 874; // returns an int, type expected is int.
    }
}

class Bar extends Foo
{
    public function fooMethod(): array
    {
        return ['something']; // returns an array, type expected int
    }
}
Run Code Online (Sandbox Code Playgroud)