10

我有界面:

interface AbstractMapper
{
    public function objectToArray(ActiveRecordBase $object);
}

和类:

class ActiveRecordBase
{
   ...
}

class Product extends ActiveRecordBase
{
   ...
}

========

但我不能这样做:

interface ExactMapper implements AbstractMapper
{
    public function objectToArray(Product $object);
}

或这个:

interface ExactMapper extends AbstractMapper
{
    public function objectToArray(Product $object);
}

我收到错误“声明必须兼容

有没有办法在 PHP 中做到这一点?

4

3 回答 3

15

不,必须完全实现接口。如果您将实现限制为更具体的子类,则它不是相同的接口/签名。PHP 没有泛型或类似机制。

当然,您始终可以手动签入代码:

if (!($object instanceof Product)) {
    throw new InvalidArgumentException;
}
于 2013-10-02T06:41:15.120 回答
0

另一种实现方式是:

class Executor
{
    public function objectToArray(AbstractMapper $var)
    {
        $this->convert($var);
    }

    private function convert(Product $var)
    {
        ...
    }
}
于 2019-02-11T10:18:47.733 回答
0

在 7.4 之后,当添加了对协变和逆变的支持时,你不能做你想做的事情,但你可以做完全相反的事情。

逆变意味着参数类型在子方法中的特定性可能低于其父方法或接口的特定类型。

例如,给定这两个类:

class Foo {}
class FooChild extends Foo {}

和这样的界面

interface A {
    public function a(FooChild $f): Foo;
}

你可以有一个实现:

class AI implements A {
    public function a(Foo $f): Foo
    {
        return $f;
    }
}

虽然实现并不完全遵循接口但它是兼容的,因为A接口的任何使用者仍然可以安全地使用AI该类,因为接口上合法的任何东西在实现上也是有效的。

于 2021-09-09T06:27:41.747 回答