user_of_toster
@user_of_toster

Является ли сужение области аргументов родительского класса нарушением LSP?

class Parent {
     constructor(public arg: any){}
}

class Child extends Parent {
    constructor(public arg: number){}
}

LSP утверждает, что элементы суперкласса могут быть заменены экземплярами подкласса, и при этом программа будет работать корректно. Относится ли это к конструкторам класса? Могут ли конструкторы подкласса сужать область аргументов, которые принимает суперкласс?
  • Вопрос задан
  • 443 просмотра
Решения вопроса 2
@vabka
Токсичный
Это не нарушает LSP, тк конструктор не является методом экземпляра
Ответ написан
bingo347
@bingo347
Ткнуть в доку лучше готового к копипасте ответа
Добавлю к Василий Банников, что:
1. хоть и в js/ts override происходит неявно, typescript не даст сделать override метода с другими параметрами (хотя с any и unknown в родителе все ок, так как unknown надтип для любого типа, а any вообще ломает типизацию). К конструктору это не относится, так как это не override.
2. LSP не про корректное поведение программы, LSP про корректную логику программы, про то что если некто ожидает инстанс Parent, а получит вместо него истанс Child, то поведение для него останется предсказуемым.
Например, если Parent предоставляет некоторую абстракцию для сохранения данных, Child1 сохраняет данные в MySQL, а Child2 в MongoDB - это соответствует LSP.
А если некий Child3 вместо сохранения данных шлет их на почту админу, то это нарушает LSP, хотя бы потому, что прочитать их впоследствии будет затруднительно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Vitsliputsli
Разумеется нарушает:
1) Не смотря на все что здесь понаписали, конструктор - это метод экземпляра. Пусть с особым синтаксическим вызовом, но не более того, и что более важно это публичный метод. Конструктор - это всего лишь синтаксический сахар, не будь его, пришлось бы после каждого создания объекта, вызывать подобный метод вручную.
2) Соответствие принципу проверяется очень легко, подставляете вместо дочернего экземпляра родительский и проверяете, что поведение не изменилось. В вашем случае очевидно, что поведение изменится, а следовательно принцип нарушается.
3) То что используется какие-то специфические для языка типы, вообще не имеет значения, поменяйте на наследственно зависимые классы и будет тоже самое. В вашем варианте, если было бы наоборот и наследник имел более широкий тип, т.е. был контрвариантен, то это не нарушало бы принцип.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы