缩小已实现方法的返回类型



我正在尝试为返回类 B 实例的类 A 和类 B 本身指定两个接口。

我在接口上声明返回类型。

假设我有两个接口。

某种存储库接口,具有返回实现 ElementInterface 的对象get()方法

<?php
namespace AppContracts;
interface RepositoryInterface {
public function get( $key ) : ElementInterface;
}

还有一个元素接口:

<?php
namespace AppContracts;
interface ElementInterface { }

现在,我对存储库的实现声明了一个返回类型,该返回类型是特定的类MyElement

<?php
namespace AppRepositories;
class MyRepository implements RepositoryInterface {
public function get( $key ) : MyElement {
// ...
}
}

其中MyElement是一些类实现ElementInterface

。这会导致致命错误:

Declaration of MyRepository::get( $key ): MyElement must be compatible with RepositoryInterface::get( $key ): ElementInterface

如果我不在接口上指定返回类型,这将完全正常工作。但是,我想限制实现RepositoryInterface的任何类返回的类的类型。

  1. 这在 PHP 7.1 中真的是不可能的吗?
  2. 如果这确实是不可能的,那是因为我的模式不正确吗?
  3. 如何在不指定此类型的实际实现的情况下声明接口方法的返回类型。

对于任何低于 7.4 的 PHP 版本,这都是不可能的。

如果您的接口包含:

public function get( $key ) : ElementInterface;

那么你的类需要:

class MyRepository implements RepositoryInterface {
public function get( $key ) : ElementInterface {
returns new MyElement();
// which in turn implements ElementInterface
}
}

实现接口的类的声明必须与接口布局的协定完全匹配。

通过声明它必须返回一个特定的接口而不是一个特定的实现,你给了你如何实现它的余地(现在你可以返回MyElementAnotherElement只要两个实现ElementInterface);但方法声明无论如何都必须相同。

看到它在这里工作。


从将于 2019 年 11 月发布的 PHP 7.4 开始,返回类型将支持协方差。到那时,这将起作用。

最新更新