Parameterkovarianz in überschreibenden Methoden
In der objektorientierten Programmierung ermöglichen überschreibende Methoden Unterklassen, ihre eigenen Versionen von Methoden zu implementieren, die in der Oberklasse definiert sind . Beim Überschreiben einer Methode müssen jedoch die Parameter und der Rückgabetyp mit der Deklaration der Oberklassenmethode kompatibel sein.
Im angegebenen Code haben wir ein Szenario mit den folgenden Schnittstellen:
<code class="php">interface Engine { function run(); } interface HydroEngine extends Engine { function run(); }</code>
Und eine ähnliche Struktur für Klassen:
<code class="php">interface Car { function setEngine(Engine $engine); } interface WaterCar extends Car { // This method is intended to override Car::setEngine() function setEngine(HydroEngine $engine); }</code>
Das Problem tritt auf, wenn versucht wird, setEngine() in WaterCar zu überschreiben:
<code class="php">Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)</code>
Dieser Fehler tritt auf, weil der Parametertyp von setEngine() in WaterCar ist HydroEngine, ein Untertyp von Engine, während der Parametertyp in der Oberklasse Car Engine ist.
Das Liskov-Substitutionsprinzip (LSP) regelt solche Szenarien. Der LSP gibt an, dass ein Subtyp (z. B. HydroEngine) für seinen Supertyp (z. B. Engine) ersetzbar sein muss, ohne die Funktionalität des Programms zu beeinträchtigen. Dieses Prinzip gilt jedoch nicht für Parametertypen in überschriebenen Methoden.
In diesem Fall implementiert WaterCar Car nicht vollständig, da es einen engeren Parametertyp in setEngine() akzeptiert. Dies liegt daran, dass ein WaterCar nur HydroEngines akzeptieren kann, während ein Car jeden Motor akzeptieren kann. Dies verstößt gegen LSP und bricht den von der Superklasse Car festgelegten Vertrag.
Um dieses Problem zu beheben, stellen Sie sicher, dass die Parametertypen in den überschriebenen Methoden mit den Deklarationen der Superklasse kompatibel sind. In diesem Beispiel könnte WaterCar::setEngine() wie folgt geändert werden:
<code class="php">function setEngine(Engine $engine): void;</code>
Diese Änderung behält die Kompatibilität mit Car::setEngine() bei und ermöglicht WaterCar gleichzeitig, sich auf die Annahme von HydroEngines zu spezialisieren.
Das obige ist der detaillierte Inhalt vonWarum kann ich keinen Subtyp im Parameter einer überschriebenen Methode verwenden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!