问题描述
为什么在PHP 7中无法使用 static
返回类型声明接口?
Why is it not possible in PHP 7, to declare an interface with a static
return type?
假设我有以下类:
interface BigNumber {
/**
* @param BigNumber $that
*
* @return static
*/
public function plus(BigNumber $that);
}
class BigInteger implements BigNumber { ... }
class BigDecimal implements BigNumber { ... }
我想强制执行 plus()
方法的返回类型为 static
,即:
I want to enforce the return type of the plus()
method to static
, that is:
-
BigInteger :: plus()
必须返回BigInteger
-
BigDecimal :: plus()
必须返回BigDecimal
BigInteger::plus()
must return aBigInteger
BigDecimal::plus()
must return aBigDecimal
我可以通过以下方式声明接口:
I can declare the interface in the following way:
public function plus(BigNumber $that) : BigNumber;
但这并不强制执行上述操作。我想做的是:
But that doesn't enforce the above. What I would like to do is:
public function plus(BigNumber $that) : static;
但到目前为止,PHP 7并不满意:
But PHP 7, to date, is not happy with it:
这是否有特定的原因,或者这是一个应该报告的错误?
Is there a specific reason for this, or is this a bug that should be reported?
推荐答案
这不是一个错误,它从面向对象的编程角度看,设计是没有意义的。
It's not a bug, it just doesn't make sense design-wise from an object-oriented programming perspective.
如果你的 BigInteger
和 BigDecimal
实现 BigNumber
,你关心他们履行的合同。在这种情况下,它是 BigNumber
的界面。
If your BigInteger
and BigDecimal
implement both BigNumber
, you care about the contract they fulfil. I this case, it's BigNumber
's interface.
所以你应该在界面中使用的返回类型是 BigNumber
因为任何针对该接口编码的人都不知道除该接口成员之外的任何其他内容。如果您需要知道返回哪一个,那么界面可能首先太宽。
So the return type you should be using in your interface is BigNumber
since anybody coding against that interface does not know anything else than members of that interface. If you need to know about which one is returned, the interface is perhaps too wide in the first place.
注意:使用泛型编程语言可以通过将返回类型指定为泛型类型来实现此效果,但PHP没有泛型,可能不会在不久的将来。
Note: programming languages with generics can achieve this effect by specifying the return type as the generic type, but PHP does not have generics and probably will not have in the near future.
这篇关于PHP 7接口中的静态返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!