Это нарушение 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) {} }
Зачем? Разве они не должны быть смертельными, так как все они противоречивы?
В первом случае это фатальная ошибка, потому что PHP требует, чтобы вы были совместимы с родителем Аннотация учебный класс:
При наследовании от абстрактного класса … сигнатуры методов должны совпадать.
то же самое верно во втором случае:
Класс, реализующий интерфейс, должен использовать те же сигнатуры методов, которые определены в интерфейсе. Невыполнение этого приведет к фатальной ошибке.
В третьем случае вы расширяете обычный класс PHP, а не абстрактный. PHP позволяет изменить подпись, хотя и с предупреждением.
Очевидно, что это не очень хорошая практика, и, как вы указываете, нарушает LSP. Просто один из многих способов, которыми PHP дает вам острые объекты, и позволяет вам навредить себе, если вы не будете осторожны. знак равно
Если вы хотите использовать LSP, вам нужно использовать интерфейс, абстрагирование или создать свой метод final
в родительском классе.
Вот пример final
: https://3v4l.org/s42XG
Других решений пока нет …