2015-06-20 31 views
9

为什么在PHP 7中无法声明带有static返回类型的界面?PHP 7界面中的静态返回类型

比方说,我有以下类别:

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

class BigInteger implements BigNumber { ... } 
class BigDecimal implements BigNumber { ... } 

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

  • BigInteger::plus()必须返回BigInteger
  • BigDecimal::plus()必须返回BigDecimal

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

public function plus(BigNumber $that) : BigNumber; 

但是,这并不执行上述。我想这样做的是:

public function plus(BigNumber $that) : static; 

但是PHP 7,到目前为止,是不满意的话:

PHP Parse error: syntax error, unexpected 'static' (T_STATIC)

是否有此特殊原因,或者这是一个错误,应该被报道?

+2

类型不变性,这就是为什么。实现/重写方法必须完全匹配PHP中的类型; '静态'不会 - 显然,因为它指的是当前的上下文,因此不能无变化。 –

回答

5

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

如果您的BigIntegerBigDecimal实现了BigNumber,那么您关心他们履行的合同。我这种情况下,它是BigNumber的界面。

所以你应该在你的界面中使用的返回类型是BigNumber,因为任何对这个接口进行编码的人都不知道除了那个接口的成员以外的任何东西。如果您需要知道返回哪一个,那么界面可能太宽了。

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

+2

我的想法是灵活的输入(例如,您可以比较'BigInteger'和'BigDecimal'),但严格的输出(无论在类上调用什么方法都应该返回同一类的实例)。也许这并不完全合理,但至少PHPdoc允许这种用法('@return static')! – Benjamin

+0

那么PHPDoc实际上并不知道什么关于'static' http://www.phpdoc.org/docs/latest/references/phpdoc/types.html,最接近的是'self',在这种情况下它与界面相同返回类型提示。 – vvondra

+2

奇怪的是,这一个:http://www.phpdoc.org/docs/latest/guides/types.html实际上是文档'static':“这个值被消费的类的对象,如果继承它将代表孩子类(参见PHP手册中的后期静态绑定)。“ – Benjamin