子 class 方法的声明必须与 PHP 中的父 class 方法兼容吗?

Must declaration of the child class method be compatible with parent class method in PHP?

这段代码 运行 没问题。

ParentClass是抽象的class。我想我可以通过

来验证
$class = new ReflectionClass('ParentClass');
$methods = $class->getMethods(ReflectionMethod::IS_ABSTRACT);

其中显示了几个方法,其中一个名为 methodA

真正让我困惑的是:

有一个ChildClass,它是一个具体的class,实现了其中一个抽象方法methodA。使用

$method = new ReflectionMethod('ChildClass', 'methodA');
var_dump($method->getParameters());

我可以验证有3个参数。因为我知道代码运行良好。我使用相同的 ReflectionMethod 来验证 ParentClass

$method = new ReflectionMethod('ParentClass', 'methodA');
var_dump($method->getParameters());

我想这会输出一个空数组,它表示 none 个参数。

为什么?可悲的是,我无法查看这些 classes 的源代码,但我一直在努力解决这个问题,但没有太大进展:

到目前为止,我只能做这样的事情。代码在 PHP5.4 中。我真的不知道如何制作一个没有参数的抽象方法 _myFunction 而是带有 3 个参数的具体子 class 方法。 PHP 使用 __call 超载,但我想这更像是一个 extending 问题。

class A {}

abstract class MyAbstractClass
{   
    //abstract public function _myFunction();// ERROR
    abstract public function _myFunction(A $a, A $b, A $c);
}

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a, A $b, A $c = null)
    {   
        echo "abc";
    }
}

$a = new Foobar();
$a->_myFunction(new A(), new A(), new A());
$a->_myFunction(new A(), new A());

//output: abcabc without error

已添加:

写下问题后,它有助于我进一步测试,我想我现在知道为什么了。子方法已为所有 3 个参数提供默认值。

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a = null, A $b = null, A $c = null)
    {
        echo "abc";
    }
}

这行得通。

根据PHP manual

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility.

Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same.

因此,父项 class 有 0 个参数,子项有 2 个 必需的 个。那就是问题所在。但是由于您更改了代码,正如您所说:

The child method has given all 3 arguments a default value.

您将子 class 中所需参数的数量减少到 0。所以它现在可以工作了。

重述。 这是错误的:

abstract class MyAbstractClass
{   
    abstract public function _myFunction(); // No parameters required
}

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a, A $b, A $c = null) // Two parameters required
    {   
        echo "abc";
    }
}

这也是错误的:

abstract class MyAbstractClass
{   
    abstract public function _myFunction(A $a, A $b, A $c); // Three parameters required
}

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a, A $b) // Two parameters required
    {   
        echo "abc";
    }
}

这个可以:

abstract class MyAbstractClass
{   
    abstract public function _myFunction(); // No parameters required
}

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a = null, A $b = null, A $c = null) // No parameters required
    {   
        echo "abc";
    }
}

这也行:

abstract class MyAbstractClass
{   
    abstract public function _myFunction(A $a, A $b, A $c);
}

class Foobar extends MyAbstractClass
{   
    public function _myFunction(A $a, A $b, A $c = null)
    {   
        echo "abc";
    }
}