Почему нарушения LSP в PHP иногда фатальные, а иногда и предупреждения?

Это нарушение 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 также поднимает фатальную ошибку:

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

Пока только это нарушение LSP поднимает предупреждение:

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

Зачем? Разве они не должны быть смертельными, так как все они противоречивы?

7

Решение

В первом случае это фатальная ошибка, потому что PHP требует, чтобы вы были совместимы с родителем Аннотация учебный класс:

При наследовании от абстрактного класса … сигнатуры методов должны совпадать.

то же самое верно во втором случае:

Класс, реализующий интерфейс, должен использовать те же сигнатуры методов, которые определены в интерфейсе. Невыполнение этого приведет к фатальной ошибке.

В третьем случае вы расширяете обычный класс PHP, а не абстрактный. PHP позволяет изменить подпись, хотя и с предупреждением.

Очевидно, что это не очень хорошая практика, и, как вы указываете, нарушает LSP. Просто один из многих способов, которыми PHP дает вам острые объекты, и позволяет вам навредить себе, если вы не будете осторожны. знак равно

Если вы хотите использовать LSP, вам нужно использовать интерфейс, абстрагирование или создать свой метод final в родительском классе.

Вот пример final: https://3v4l.org/s42XG

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]