2015-06-20 57 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