Php type hinting nicht immer zusammen mit interfaces und abstrakten Klassen?
Ich denke, es wird viel leichter sein, zu sehen, dass das problem in ein code-Beispiel schreiben die Frage in den ersten Platz. Hier ist mein php code:
<?php
interface AnInterface
{
public function method();
}
class AClass implements AnInterface
{
public function method()
{
echo __METHOD__;
}
}
abstract class AnAbstractClass
{
abstract public function method( AnInterface $Object );
}
class ConcreteClass extends AnAbstractClass
{
public function method( AClass $Object )
{
$Object->method();
}
}
$Object1 = new ConcreteClass();
$Object2 = new AClass();
$Object1->method( $Object2 );
Dem obigen code die folgende Fehlermeldung verursacht:
Fatal error: Declaration of ConcreteClass::Methode() muss kompatibel mit der AnAbstractClass::Methode()
Das problem ist, dass php nicht zu sein scheinen, erkennen die Unterschriften von AnAbstractClass::Methode und ConcreteClass::Methode als kompatibel. Mache ich etwas falsch? Danke!
- Bitte, bitte kommen Sie in die Gewohnheit der Entsendung der Fehlermeldung, der code wird generiert. Posting-code ohne die Buchung der Ausgabe (oder Fehler) ist nutzlos.
Du musst angemeldet sein, um einen Kommentar abzugeben.
PHP ist richtig, Sie sind nicht kompatibel. Da nur Instanzen von
AClass
(oder seine Kinder) zu übergebenConcreteClass::method
, du brichst den Vertrag, denAnAbstractClass
bietet: einer Ihrer Unterklassen müssen akzeptierenAnInterface
als argument für seinemethod()
.Wenn Ihr Beispiel arbeitete, und ich hatte eine andere Klasse
BClass
UmsetzungAnInterface
sein, hätten wir eine situation, wo nachAnAbstractClass
,method()
sollten akzeptieren, Instanzen vonBClass
, während nach derConcreteClass
sollte es auch nicht.Ändern Sie Ihre Signatur-für
ConcreteClass::method
zu entsprechen, die vonAnAbstractClass::method
.Nicht berechnen. Wir hatten die gleiche Diskussion gestern:
Können parameter-Typen spezialisiert werden in PHP
Alle Ihre abgeleiteten Klassen implementieren müssen, die Signaturen identisch.
Dies ist etwas, das im Idealfall werden zur Laufzeit überprüft. Aber in PHP der parser führt. (Um das zu kompensieren, PHP nicht überprüfen private/protected-Attribut-Zugriff auf der parsing-Zeit, aber lassen Sie dass man sich eher sprengen zur Laufzeit.)
Wenn Sie erzwingen möchten ein strenger Typ, würde ich dir raten:
assert($Object instanceof AClass);
Hier ist ein Beispiel, das zeigt, warum ist dies nicht erlaubt:
Wäre dies ein Gültiger code, aber es wäre ein Fehler, wenn Sie passieren einen
ConcreteClass
zu moo, weil seine MethodeConcreteClass::method
nicht erlaubenBClass
.Es ist kompliziert, aber es ist einfacher zu verstehen, wenn Sie ein Beispiel sehen.