メソッドのパラメータとしてサブタイプを使用して、子クラスのメソッドをオーバーライドするときにPHPで矛盾があるようです。私はコードで説明している場合それは簡単です:PHPでサブタイプパラメータを使用してメソッドをオーバーライドするときの動作が矛盾します
interface IngredientInterface {}
interface TomatoInterface extends IngredientInterface {}
class Tomato implements TomatoInterface {}
class Soup {
public function __construct(IngredientInterface $ingredient) {}
public function foo(IngredientInterface $ingredient) {}
}
class TomatoSoup extends Soup {
public function __construct(TomatoInterface $tomato) { parent::__construct($tomato); }
public function foo(TomatoInterface $ingredient) { parent::foo($ingredient); }
}
一つは、エラー報告の動作は()メソッドオーバーライド__construct()とfooの間で同一であることを期待するだろうが、そうではありません。
__construct()メソッドはPHP 5.5.38、5.6.19にエラーを生成せず、7.0.4
のfoo()メソッドは、5.5.38および5.6.19に次のエラーを生成します。
Strict Standards: Declaration of TomatoSoup::foo() should be compatible with Soup::foo(IngredientInterface $ingredient) in H:\webroot\test.php on line 16
および7.0.4で:
Warning: Declaration of TomatoSoup::foo(TomatoInterface $ingredient) should be compatible with Soup::foo(IngredientInterface $ingredient) in H:\webroot\test.php on line 16
今、私は、エラーの種類がE_WARNINGにE_STRICTから変更されたことを心配していないよ、私は罰金の解析コンストラクタの矛盾にもっと心配だけど、 foo( )メソッドではありません。
これはPHPのバグですか?私はそれをbugs.php.netに報告すべきでしょうか?
ご返信ありがとうございます。はい、あなたのコードは正常に動作することに同意します。これに対応して、ISPに違反しないインターフェースを拡張することに問題はありません。また、必ずしもメソッド引数をサブタイプ化する必要はありませんが、SOLIDに違反しない他の方法があります。私はPHPがメソッド内のLSPの違反を防ぐことを心配していますが、コンストラクタでそれを許可しています。 @DeveloperChrisは、この質問でそれを説明しています... PHPの乗組員が怠け者になったようです:(http://stackoverflow.com/questions/13423494/why-is-overriding-method-parameters-a-violation-of-strict-standards -in-php –