Принцип подстановки Лискова (LSP) гласит, что если объект o1 является типом S и его можно заменить на объект o2, который является типом T, не нарушая первоначальное поведение (поведение) всех его пользователей, то S является подтипом Т.
Типичным примером, показывающим нарушение LSP, является Rectangle и его производный тип Square. Аргумент заключается в том, что хотя Квадрат интуитивно кажется подтипом Прямоугольника, но существует некоторое поведение Квадрата, которое отличается от Прямоугольника. Вывод таков: квадрат не может быть подтипом Rectangle от LSP.
Все объяснения, которые я обнаружил, заканчиваются там, и я считаю это бесполезным. Я хочу знать, что мне делать, если у меня возникла эта проблема? Создать S, который не является подтипом T, и что тогда? Какие решения у меня есть, чтобы решить это?
Может кто-нибудь просветить меня ответом на нависший вопрос?
редактировать: Вместо того, чтобы разрабатывать пример здесь, я отсылаю вас к этому статья.
Ты можешь использовать ‘ИМЕЕТ’ или же «ИСПОЛЬЗУЕТ» отношения, если вы не можете установить ‘ЭТО’ отношения.
Это означает, что вместо того, чтобы класс B наследовал от класса A, вы можете иметь класс B, содержащий экземпляр класса A. Это также хорошая практика кодирования, чтобы избежать тесной связи между классом A и классом B.
Этот вопрос рассматривается в книге «Эффективное С ++, 3-е издание» Скотта Мейерса, Эддисон Уэсли, май 2005 г. В главе 6, пункт 32.
Там Мейерс делает образец класса для Rectangle и класс для Square, который наследует первый и подробно рассказывает о возникающих проблемах, используя утверждения.
Вывод пункта:
«Общественное наследование означает« есть ». Все, что относится к базе
классы также должны применяться к производным классам, потому что каждый производный
Объект класса является объектом базового класса. »
В настоящее время книгу можно найти или купить в интернете.
LSP является более точным определением отношения «is-a», если ваш класс нарушает LSP не является подходящим кандидатом для получения из базового класса. Это сигнал о том, что в вашем дизайне что-то не так.
Следует отметить два момента: нарушение LSP приведет к нарушению базового класса, а не производного класса, это очень опасно в устаревшем коде с очень небольшим охватом тестов, то, что имеет четкие отношения «есть» в математическом мире (например, квадрат и прямоугольник) они могут не разделять эти отношения в домене вашего приложения.
Вы можете извлечь общие свойства в интерфейс или абстрактный тип и использовать его как основу. Различия все еще могут быть реализованы в производном типе.
Таким образом, вы сохраняете свое IS-отношение.
Урок, который нужно извлечь из LSP и пример прямоугольника / квадрата, заключается в том, что ЭТО не имеет ничего общего с математикой, биологией или чем-то, что кажется очевидным ЭТО интуицией
ЭТО это исключительно отношения поведения. Квадрат не является прямоугольником в ООП, потому что он не имеет такого же поведения. Но у прямоугольника такое же поведение, как у квадрата, плюс некоторые дополнительные, которые не нарушают поведения квадрата. Так что в ООП прямоугольник ЭТО квадратный, и имеет смысл реализовать его таким образом, даже если он не поддается математике и интуиции.