2016-06-17 5 views
7

Ten LSP naruszenie raises a Fatal Error:Dlaczego naruszenia LSP w PHP są czasami śmiertelne, a czasem ostrzeżenia?

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

Ten LSP naruszenie 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) {} } 

Chociaż naruszenie LSP tylko raises a Warning:

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

Dlaczego? Czy nie wszystkie powinny być śmiertelne, ponieważ wszystkie są sprzeczne?

Odpowiedz

8

W pierwszym przypadku jest to błąd krytyczny, ponieważ PHP requires you to be compatible with a parent abstract class:

Kiedy dziedziczenie z klasy abstrakcyjnej ... podpisy metody muszą być zgodne.

same is true w drugim przypadku:

klasa tworzenia interfejsu muszą stosować te same metody, jak podpisy są zdefiniowane w interfejsie. Nieprzestrzeganie tego spowoduje błąd krytyczny.

W trzecim przypadku rozszerzasz normalną klasę PHP, a nie abstrakcję. PHP pozwala na zmianę podpisu, aczkolwiek z ostrzeżeniem.

Oczywiście nie jest to dobra praktyka i narusza LSP, jak wskazujesz. To tylko jeden z wielu sposobów, w jaki PHP daje ci ostre przedmioty i pozwala zranić się, jeśli nie jesteś ostrożny. =)

Jeśli chcesz wymusić LSP, musisz użyć interfejsu, abstrakcji lub uczynić swoją metodę final w klasie nadrzędnej.

Oto przykład z final: https://3v4l.org/s42XG

+0

śledzę mechanikę, ale nie rozumiem uzasadnienie. Zeev dodał ograniczenie w wersji 5.0.0-rc2 zgodnie z [Changelog] (http://php.net/ChangeLog-5.php), ale nie jest dla mnie jasne, czy było to dla LSP czy z innego powodu, a jeśli polimorficzny jest - relacje zostały pominięte dla BC z klasami PHP 4. – bishop

+0

"PHP daje ostre przedmioty i pozwala zranić się, jeśli nie jesteś ostrożny". Tak prawdziwe. Przypuszczam, że rozsądek ginie w mgłach czasu. – bishop

Powiązane problemy