2015-06-20 21 views
9

Dlaczego w PHP 7 nie jest możliwe zadeklarowanie interfejsu z typem zwracanym static?statyczny typ powrotu w interfejsach PHP 7

Powiedzmy mam następujących klas:

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

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

Chcę wymusić typ zwracanej metody plus() do static, czyli:

  • BigInteger::plus() musi zwrócić BigInteger
  • BigDecimal::plus() musi zwrócić BigDecimal

mogę zadeklarować interfejs w następujący sposób:

public function plus(BigNumber $that) : BigNumber; 

Ale to nie wymusza wyżej. Co chciałbym zrobić, to:

public function plus(BigNumber $that) : static; 

Ale PHP 7, do tej pory nie jest z niego zadowolony:

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

Czy istnieje szczególny powód do tego, czy jest to błąd, który powinien być zgłaszane?

+2

Nośnik typu, dlatego. Implementacje/nadpisywanie metod musi być zgodne z typem dokładnie w PHP; 'static' nie - oczywiście, ponieważ odnosi się do bieżącego kontekstu i dlatego nie może być inwarianctwem. –

Odpowiedz

5

To nie jest błąd, po prostu nie ma sensu, jeśli chodzi o projektowanie z perspektywy programowania obiektowego.

Jeśli twoje BigInteger i BigDecimal wykonują zarówno BigNumber, dbasz o umowę, którą wypełniają. W tym przypadku jest to interfejs BigNumber.

Tak więc typem zwracanym, który powinieneś używać w interfejsie, jest BigNumber, ponieważ każdy programujący go interfejs nie zna niczego innego niż członkowie tego interfejsu. Jeśli chcesz wiedzieć, który z nich jest zwrócony, interfejs jest prawdopodobnie za szeroki.

Uwaga: języki programowania z generics mogą osiągnąć ten efekt, określając typ zwracany jako typ ogólny, ale PHP nie ma generycznych i prawdopodobnie nie będzie miał w najbliższej przyszłości.

+2

Moim pomysłem było być elastycznym na wejściu (można porównać np. 'BigInteger' z' BigDecimal'), ale ścisłe na wyjściu (jakakolwiek metoda wywołana na klasie powinna zwrócić instancję tej samej klasy). Może to nie ma większego sensu, ale przynajmniej PHPdoc pozwala na tego rodzaju użycie ('@return static')! – Benjamin

+0

Cóż, PHPDoc w rzeczywistości nie wie nic o 'static' http://www.phpdoc.org/docs/latest/references/phpdoc/types.html, najbliższe jest' self', które w tym przypadku jest identyczne z interfejsem typ wskazówki powrotu. – vvondra

+2

Weird, ten: http://www.phpdoc.org/docs/latest/guides/types.html faktycznie dokumenty 'static':" obiekt klasy, w której ta wartość została zużyta, jeśli jest dziedziczona, będzie reprezentować dziecko klasa (zobacz późniejsze wiązanie statyczne w podręczniku PHP). " – Benjamin