缩小实现方法的返回类型 [英] Narrowing-down the return type of an implemented method

查看:95
本文介绍了缩小实现方法的返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to specify two interfaces for class A that returns instances of class B, and for class B itself.

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

I'm declaring return types on the interface.

说我有两个界面.

某种RepositoryInterface,它具有get()方法,该方法返回实现ElementInterface的对象

Some kind of RepositoryInterface, that has a get() method that returns an object implementing the ElementInterface

<?php

namespace App\Contracts;

interface RepositoryInterface {

    public function get( $key ) : ElementInterface;

}

和元素接口:

<?php

namespace App\Contracts;

interface ElementInterface { }

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

Now, my implementation of the repository declares a return-type that is a specific class MyElement.

<?php

namespace App\Repositories;

class MyRepository implements RepositoryInterface {

    public function get( $key ) : MyElement {
        // ...
    }

}

其中MyElement是实现ElementInterface的某些类.

Where MyElement is some class implementing ElementInterface.

...这将导致致命错误:

... this results in a fatal error:

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

如果我不在接口上指定返回类型,则可以很好地工作.但是,我想限制任何实现RepositoryInterface的类返回的类的类型.

If I would not specify the return types on the interface, this would work perfectly fine. Yet, I want to constrain the type of class returned by any class implementing the RepositoryInterface.

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

推荐答案

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

This is not possible with any version of PHP lower than 7.4.

如果您的界面包含:

public function get( $key ) : ElementInterface;

然后您的课程必须是:

class MyRepository implements RepositoryInterface {

    public function get( $key ) : ElementInterface {

        returns new MyElement();
        // which in turn implements ElementInterface
    }
}

实现接口的类的声明必须完全匹配完全由接口制定的合同.

The declaration of a class implementing an interface has to match exactly the contract laid out by the interface.

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

By declaring that it has to return a particular interface instead of an specific implementation, you are giving you leeway on how to implement it (now you could return MyElement or AnotherElement as long as both implemented ElementInterface); but the method declaration has to be the same anyway.

此处看到它正常运行.

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

Starting with PHP 7.4, due to be released in November 2019, covariance will be supported for return types. By then, this would work.

这篇关于缩小实现方法的返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆