Parameter Covariance in Overriding Methods
In object-oriented programming, overriding methods allows subclasses to implement their own versions of methods defined in the superclass. When overriding a method, however, the parameters and return type must be compatible with the superclass method's declaration.
In the given code, we have a scenario with the following interfaces:
<code class="php">interface Engine { function run(); } interface HydroEngine extends Engine { function run(); }</code>
And a similar structure for classes:
<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>
The issue arises when trying to override setEngine() in WaterCar:
<code class="php">Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)</code>
This error occurs because the parameter type of setEngine() in WaterCar is HydroEngine, a subtype of Engine, while the parameter type in the superclass Car is Engine.
The Liskov Substitution Principle (LSP) governs such scenarios. The LSP states that a subtype (e.g., HydroEngine) must be substitutable for its supertype (e.g., Engine) without breaking the program's functionality. This principle, however, does not apply to parameter types in overridden methods.
In this case, WaterCar does not fully implement Car because it accepts a narrower parameter type in setEngine(). This is because a WaterCar may only accept HydroEngines, whereas a Car can accept any Engine. This violates LSP and breaks the contract established by the superclass Car.
To resolve this issue, ensure that the parameter types in the overridden methods are compatible with the superclass's declarations. In this example, WaterCar::setEngine() could be modified as follows:
<code class="php">function setEngine(Engine $engine): void;</code>
This modification maintains the compatibility with Car::setEngine() while allowing WaterCar to specialize in accepting HydroEngines.
The above is the detailed content of Why Can't I Use a Subtype in an Overridden Method's Parameter?. For more information, please follow other related articles on the PHP Chinese website!