新しいパラメータとして子インターフェイスを使用したメソッド パラメータのオーバーライド: 失敗する理由
PHP では、メソッド オーバーライドによりサブクラスの動作を再定義できます親クラスから継承されたメソッドの。ただし、型の互換性と OOP 原則の遵守を確保するために、特定の制限が設けられています。
次のコード スニペットを考えてみましょう。これは、WaterCar インターフェイスの setEngine() メソッドを、HydroEngine 型の新しいパラメータでオーバーライドしようとしています。 :
<code class="php"><?php interface Engine { function run(); } interface HydroEngine extends Engine { function run(); } interface Car { function setEngine(Engine $engine); } interface WaterCar extends Car { function setEngine(HydroEngine $engine); } ?></code>
このコード スニペットは次のエラーで失敗します:
Fatal error: Declaration of WaterCar::setEngine() must be compatible with Car::setEngine(Engine $engine)
このエラーの理由は、メソッド パラメーターのオーバーライドがリスコフ置換原則に違反するためです。 WaterCar インターフェイスは、setEngine() メソッドに対して Car インターフェイスとは異なるパラメータ タイプを宣言します。
具体的には、Car インターフェイスは Engine タイプのパラメータを期待するのに対し、WaterCar インターフェイスは HydroEngine タイプのパラメータを期待します。 HydroEngine は Engine のサブクラスですが、それでも別の型とみなされます。
その結果、WaterCar を実装するクラスは、Engine パラメーターを受け入れることができないため、Car を完全に実装できない可能性があります。これは、予期しない動作を引き起こすことなく、サブタイプをその親タイプの代わりに使用できる必要があるというリスコフ置換原則を破ります。
言い換えれば、関数が Car を予期している場合、それはできるはずです。 WaterCar を問題なく受け入れることができます。ただし、この場合、関数は Engine パラメーターを期待しているため、WaterCar を渡すと失敗します。
この問題を解決するには、親インターフェイスと子インターフェイスの間でメソッド パラメーターの互換性を維持する必要があります。特定のサブクラスに特別な動作が必要な場合は、パラメーターの型をオーバーライドするのではなく、追加のメソッドを定義することをお勧めします。
以上がPHP で新しいパラメータとして子インターフェイスを使用してメソッド パラメータをオーバーライドできないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。