2015-06-20 17 views
9

Warum ist es in PHP 7 nicht möglich, eine Schnittstelle mit einem Rückgabetyp static zu deklarieren?statische Rückgabetyp in PHP 7 Schnittstellen

Lassen Sie uns sagen, ich habe die folgenden Klassen:

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

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

ich den Rückgabetyp der plus() Methode static erzwingen möchten, das heißt:

  • BigInteger::plus() müssen BigInteger zurückkehren
  • BigDecimal::plus() muss eine BigDecimal
  • zurückgeben

ich die Schnittstelle auf folgende Weise erklären können:

public function plus(BigNumber $that) : BigNumber; 

aber, dass die oben nicht erzwingen ist. Was würde Ich mag zu tun ist:

public function plus(BigNumber $that) : static; 

Aber PHP 7 bis heute nicht mit ihm glücklich ist:

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

Gibt es einen bestimmten Grund dafür, oder ist dies ein Fehler, der sollte gemeldet werden?

+2

Typ Invarianz, deshalb. Implementierungen/überschreibende Methoden müssen genau dem Typ in PHP entsprechen; "Statisch" ist nicht - offensichtlich, weil es sich auf den aktuellen Kontext bezieht und daher nicht invariant sein kann. –

Antwort

5

Es ist kein Fehler, es macht nur aus einer objektorientierten Programmierungsperspektive keinen Sinn.

Wenn Ihre BigInteger und BigDecimal beide BigNumber implementieren, kümmern Sie sich um den Vertrag, den sie erfüllen. In diesem Fall ist es die Schnittstelle BigNumber.

Also der Rückgabetyp, den Sie in Ihrer Schnittstelle verwenden sollten, ist BigNumber, da jeder, der gegen diese Schnittstelle kodiert, nichts anderes als Mitglieder dieser Schnittstelle kennt. Wenn Sie wissen möchten, welche zurückgegeben wird, ist die Schnittstelle vielleicht zu breit.

Hinweis: Programmiersprachen mit Generika können diesen Effekt erreichen, indem Sie den Rückgabetyp als generischen Typ angeben, aber PHP hat keine Generika und wird wahrscheinlich in naher Zukunft nicht haben.

+2

Meine Idee war es, bei der Eingabe flexibel zu sein (man kann beispielsweise einen 'BigInteger' mit einem' BigDecimal' vergleichen), aber streng auf die Ausgabe (egal welche Methode für eine Klasse aufgerufen wird, sollte eine Instanz derselben Klasse zurückgeben). Das macht vielleicht keinen Sinn, aber PHPdoc erlaubt zumindest diese Art der Verwendung ('@return static')! – Benjamin

+0

Naja PHPDoc weiß eigentlich nichts über 'static' http://www.phpdoc.org/docs/latest/references/phpdoc/types.html, am nächsten ist' self', was in diesem Fall identisch ist mit der Schnittstelle Rückgabetyp Hinweis – vvondra

+2

Seltsam, dieser: http://www.phpdoc.org/docs/latest/guides/types.html dokumentiert tatsächlich 'static':" ein Objekt der Klasse, in der dieser Wert verbraucht wurde, wenn er vererbt wird, repräsentiert er das Kind Klasse (siehe späte statische Bindung im PHP-Handbuch). " – Benjamin