首页 > 解决方案 > 在 PHP7 中,为什么子类的方法可以定义返回类型,而被覆盖的父方法没有?

问题描述

考虑以下代码片段:

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

class Bar extends Foo
{
    public function fooMethod(): array
    {
        return ['something'];
    }
}

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

标签: phpinheritance

解决方案


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

乙:

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

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

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

推荐阅读