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

时间:2018-03-18 20:43:23

标签: php oop php-7 return-type

我试图为A类指定两个接口,它们返回B类的实例,并为B类本身指定实例。

我在界面上声明了返回类型。

说我有两个接口。

某种RepositoryInterface,它有一个Scene scene = new Scene(grid, 400, 275); scene.getStylesheets().add(this.getClass().getResource("/stylesheet.css").toExternalForm()); this.setScene(scene); 方法,返回一个实现ElementInterface的对象

get()

一个元素界面:

<?php

namespace App\Contracts;

interface RepositoryInterface {

    public function get( $key ) : ElementInterface;

}

现在,我对存储库的实现声明了一个返回类型,它是一个特定的类<?php namespace App\Contracts; interface ElementInterface { }

MyElement

其中<?php namespace App\Repositories; 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 的任何类返回的类的类型。

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

2 个答案:

答案 0 :(得分:2)

这在PHP 7.1和任何其他版本中都是不可能的。

如果您的界面包含:

class MyRepository implements RepositoryInterface {

    public function get( $key ) : ElementInterface {

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

然后你的班级必须是:

MyElement

实现接口的类的声明必须匹配完全接口所规定的合同。

通过声明它必须返回特定的接口而不是特定的实现,您可以给予您如何实现它的余地(现在只要两者都实现,您就可以返回AnotherElementElementInterface function addParams(){ let items = $('.duplicate').length; items -= 1; $('.duplicate:last input.item_name').attr('name', function() { return `contribution[item_name_${items}]`; }); $('.duplicate:last input.item_quantity').attr('name', function() { return `contribution[item_quantity_${items}]`; }); $('.duplicate:last select.item_type').attr('name', function() { return `contribution[item_type_${items}]`; }); } );但方法声明无论如何都必须相同。

看到它正常工作here

答案 1 :(得分:0)

一年左右后很高兴回答我自己的问题:

这将在PHP 7.4中实现

变为可能:

interface X {
  function m(Y $z): X;
}
interface Y extends X {
  // not permitted but type-safe
  function m(X $z): Y;
}

查看此RFC