オーバーライド メソッドにおけるパラメーターの共分散
オブジェクト指向プログラミングでは、メソッドをオーバーライドすることで、サブクラスがスーパークラスで定義されたメソッドの独自のバージョンを実装できるようになります。 。ただし、メソッドをオーバーライドする場合、パラメーターと戻り値の型はスーパークラス メソッドの宣言と互換性がある必要があります。
指定されたコードには、次のインターフェイスを持つシナリオがあります:
<code class="php">interface Engine { function run(); } interface HydroEngine extends Engine { function run(); }</code>
クラスの同様の構造:
<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>
で setEngine() をオーバーライドしようとすると問題が発生します。 WaterCar:
<code class="php">Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)</code>
このエラーは、WaterCar の setEngine() のパラメータ タイプが Engine のサブタイプである HydroEngine であるのに対し、スーパークラス Car のパラメータ タイプは Engine であるために発生します。
リスコフ置換原則 (LSP) は、このようなシナリオを管理します。 LSP は、プログラムの機能を損なうことなく、サブタイプ (例: HydroEngine) をそのスーパータイプ (例: Engine) と置き換えることができる必要があると規定しています。ただし、この原則は、オーバーライドされたメソッドのパラメーターの型には適用されません。
この場合、WaterCar は setEngine() でより狭いパラメーターの型を受け入れるため、Car を完全には実装しません。これは、WaterCar は HydroEngine のみを受け入れることができるのに対し、Car は任意のエンジンを受け入れることができるためです。これは LSP に違反し、スーパークラス Car によって確立されたコントラクトを破ります。
この問題を解決するには、オーバーライドされたメソッドのパラメーターの型がスーパークラスの宣言と互換性があることを確認してください。この例では、WaterCar::setEngine() は次のように変更できます:
<code class="php">function setEngine(Engine $engine): void;</code>
この変更により、Car::setEngine() との互換性が維持されながら、WaterCar が HydroEngine の受け入れに特化できるようになります。
以上がオーバーライドされたメソッドのパラメータでサブタイプを使用できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。