2016-06-17 5 views
7

Dieser LSP Verletzung raises a Fatal Error:Warum sind LSP-Verletzungen in PHP manchmal tödlich und manchmal Warnungen?

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

Dieser LSP Verletzung 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) {} } 

Während diese LSP Verletzung nur raises a Warning:

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

Warum? Sollten sie nicht alle fatal sein, da sie alle kontravariant sind?

Antwort

8

Im ersten Fall ist es ein fataler Fehler, weil PHP requires you to be compatible with a parent abstract class:

Wenn von einer abstrakten Klasse erbt ... Signaturen der Methoden müssen übereinstimmen.

Die same is true im zweiten Fall:

Die Klasse der Schnittstelle implementieren müssen exakt die gleichen Methodensignaturen verwenden, wie in der Schnittstelle definiert sind. Andernfalls wird ein schwerwiegender Fehler angezeigt.

Im dritten Fall erweitern Sie eine normale PHP-Klasse, nicht abstrakt. Mit PHP können Sie die Signatur ändern, allerdings mit einer Warnung.

Es ist offensichtlich keine gute Praxis und verletzt LSP, wie Sie darauf hinweisen. Nur eine der vielen Möglichkeiten, mit denen Sie scharfe Objekte erhalten und sich verletzen können, wenn Sie nicht vorsichtig sind. =)

Wenn LSP erzwungen werden soll, müssen Sie eine Schnittstelle verwenden, abstrakt, oder machen Sie Ihre Methode final in der Elternklasse.

Hier ist ein Beispiel von final: https://3v4l.org/s42XG

+0

ich die Mechanik folgen, aber ich verstehe nicht, die Gründe. Zeev hat die Einschränkung in 5.0.0-rc2 gemäß [Changelog] (http://php.net/ChangeLog-5.php) hinzugefügt, aber es ist mir nicht klar, ob das für LSP oder einen anderen Grund war und ob es polymorph ist -a Relationen wurden für BC mit PHP 4-Klassen übersprungen. – bishop

+0

"PHP gibt Ihnen scharfe Objekte, und Sie können sich verletzen, wenn Sie nicht aufpassen". So wahr. Ich nehme an, die Logik ist im Nebel der Zeit verloren. – bishop

Verwandte Themen