PHP 7接口中的静态返回类型

Ben*_*min 15 php interface php-7

为什么在PHP 7中无法声明具有static返回类型的接口?

假设我有以下课程:

interface BigNumber {
    /**
     * @param BigNumber $that
     *
     * @return static
     */
    public function plus(BigNumber $that);
}

class BigInteger implements BigNumber { ... }
class BigDecimal implements BigNumber { ... }
Run Code Online (Sandbox Code Playgroud)

我想执行的返回类型plus()的方法static,那就是:

  • BigInteger::plus() 必须退货 BigInteger
  • BigDecimal::plus() 必须退货 BigDecimal

我可以通过以下方式声明接口:

public function plus(BigNumber $that) : BigNumber;
Run Code Online (Sandbox Code Playgroud)

但这并没有强制执行上述规定.我想做的是:

public function plus(BigNumber $that) : static;
Run Code Online (Sandbox Code Playgroud)

但到目前为止,PHP 7并不满意:

PHP解析错误:语法错误,意外'静态'(T_STATIC)

是否有特定原因,或者这是一个应该报告的错误?

Ben*_*min 14

2020年更新

PHP 8 中引入了静态返回类型。


vvo*_*dra 6

这不是一个错误,从面向对象的编程角度看它在设计上没有意义.

如果您BigInteger同时BigDecimal执行这两项工作BigNumber,您就会关心他们履行的合同.我是这个例子,它BigNumber是界面.

因此,您应该在界面中使用的返回类型是BigNumber因为对该接口进行编码的任何人都不知道除该接口的成员之外的任何其他内容.如果您需要知道返回哪一个,那么界面可能太宽了.

注意:使用泛型的编程语言可以通过将返回类型指定为泛型类型来实现此效果,但PHP不具有泛型,并且可能在不久的将来不具有泛型.

  • 我的想法是在输入上保持灵活性(你可以比较一个`BigInteger`和一个'BigDecimal`),但输出是严格的(无论在类上调用什么方法都应该返回同一个类的实例).也许这没有任何意义,但至少PHPdoc允许这种用法(`@return static`)! (6认同)
  • 很奇怪,这个:http://www.phpdoc.org/docs/latest/guides/types.html实际上是文件`static`:"这个值被消耗的类的对象,如果继承它将代表子类.(请参阅PHP手册中的后期静态绑定)." (4认同)
  • 我至少可以找到一种“合法”用法 - 我正在创建抽象模型类,并且我有 find 功能。如果假设有 UserModel 派生 AbstractModel,我在 AbstractModel 中找到了逻辑。该逻辑取决于在 UserModel 中实现的某些内容(即 UserModel 名称)。现在,我不仅希望 UserModel::find() 返回 UserModel 的实例,还需要 UserModel 定义的一些详细信息。这样,就没有合乎逻辑的方法让我们说 UserModel::find() 返回 PostModel ,它包含另一个抽象静态函数,该函数为适当的表配置抽象模型。 (2认同)