2016-06-17 2 views
7

このLSP違反raises a Fatal ErrorPHPでLSP違反が致命的で、時には警告が発生するのはなぜですか?

abstract class AbstractService { } 
abstract class AbstractFactory { abstract function make(AbstractService $s); } 
class ConcreteService extends AbstractService { } 
class ConcreteFactory extends AbstractFactory { function make(ConcreteService $s) {} } 

このLSP違反also raises a Fatal Error

interface AbstractService { } 
interface AbstractFactory { function make(AbstractService $s); } 
class ConcreteService implements AbstractService { } 
class ConcreteFactory implements AbstractFactory { function make(ConcreteService $s) {} } 

ながら、このLSP違反のみraises a Warning

class Service { } 
class Factory { function make(Service $s) {} } 
class MyService extends Service { } 
class MyFactory extends Factory { function make(MyService $s) {} } 

なぜ?彼らはすべて反禁忌であるので、彼らはすべて致命的ではありませんか?最初のケースで

答えて

8

PHP requires you to be compatible with a parent abstract classので、それは致命的なエラーです:抽象クラスから継承する場合は

...メソッドのシグネチャが一致している必要があります。第二の場合に

same is true

インタフェースで定義されているようにインターフェースを実装するクラスは、全く同じメソッドシグネチャを使用しなければなりません。そうしないと、致命的なエラーが発生します。

3番目のケースでは、抽象クラスではなく通常のPHPクラスを拡張します。 PHPでは、警告を表示しても署名を変更することができます。

明らかに良い習慣ではなく、あなたが指摘しているようにLSPに違反しています。 PHPがあなたに鋭いオブジェクトを与える多くの方法のうちの1つだけです。あなたが慎重でない場合には、あなた自身を傷つけることができます。 =)

LSPを適用する場合は、インターフェイス、抽象的なを使用するか、親クラスのメソッドを作成する必要があります。

はここfinalの例です:https://3v4l.org/s42XG

+0

私はメカニックに従いますが、私は理論的根拠を理解していません。 Zeevは5.0.0-rc2の制限を[Changelog](http://php.net/ChangeLog-5.php)に従って追加しましたが、それがLSPか他の理由かどうか、多型がPHP 4クラスでBCの関係をスキップしました。 – bishop

+0

"PHPはあなたに鋭いオブジェクトを与え、気をつけなければあなたを傷つけることができます"。仰るとおり。私は時間の霧の中で理論的根拠が失われていると思う。 – bishop

関連する問題