LINUX.ORG.RU

Liskov Substitution Principle и кругоэлипс


0

1

Соглсно LSP, если S - подтип T, то объекты типа S могут быть безопасно подставлены вместо объектов типа T. Это одно из основных положений ООП.

Теперь, есть классическая задачка, в которой круг нельзя наследовать от эллипса, потому что нарушается LSP. Несмотря на то, что круг - частный случай эллипса.

На практике же получается, что у отношения общий случай <-> частный случай дофига общего кода, а самый лучший способ уменьшения дублирования - как раз наследование. В реальном коде (почти всём, который я когда-либо видел), на данный принцип жестко забивали. Например, если наследник не может реализовать какой-то метод (он не имеет для него смысла), метод реализуется выбросом исключения «из этого объекта нельзя вызывать этот метод!». Или наоборот, если метод имеет смысл только у наследника, похожая ошибка выкидывается в методе суперкласса, «извините, но перед использованием этот метод нужно переопределить!».

Можете поделиться, как разруливать такие ситуации с дублированием кода расово-верно? На примере того же эллипса и круга.

(Если это важно, подразумевается языки с ООП, аналогичном Java (или более свободные языки, с искусственно наложенными ограничениями для симуляции строгой явной статической типизации).

★★★★☆

Последнее исправление: stevejobs (всего исправлений: 1)

Что значит «классическая задачка, в которой круг нельзя наследовать от эллипса»? Что это за задачка? «Круг нельзя наследовать от эллипса» - это условие задачки? А откуда оно взялось? Ну хорошо, если такое условие - ну не наследуйте, в чём проблема непонятно.

Если говорить о наследовании круга от эллипса - то я не очень понимаю, почему нельзя.

kiverattes ★☆
()

А в каком месте при наследовании круга от эллипса нарушается этот самый LSP? И о каких методах идет речь?

AIv ★★★★★
()

>Теперь, есть классическая задачка, в которой круг нельзя наследовать от эллипса, потому что нарушается LSP

Нельзя, если объект мутабельный. Ежели нет — наследуйте на здоровье.

Sectoid ★★★★★
()
Ответ на: комментарий от stevejobs

>Предположим, что объект мутабельный.

Если мутабельный, то наследовать нельзя.

Что делать с дублированием кода?

Можно вынести иммутабельный интерфейс и реализовывать его и в эллипсе, и в круге (это безопасно). Весь код, который можно реализовать средствами этого интерфейса будет повторно используемым. Прочий код придется отдублировать (что и будет ИМХО семантически верно,).

Sectoid ★★★★★
()

Теперь, есть классическая задачка, в которой круг нельзя наследовать от эллипса, потому что нарушается LSP.

Пока не ломаются инварианты, ничего не нарушается. Пока не определено поведение, ни о каком принципе не может быть и речи.

LSP это проблема имплементации, а не иерархии классов.

baverman ★★★
()

Ничего не понял, но ты путаешь круг и окружность :)

o
()
Ответ на: комментарий от baverman

> Пока не определено поведение, ни о каком принципе не может быть и речи.

Object Oriented Programming == Behavior Oriented Programming?

stevejobs ★★★★☆
() автор топика
Ответ на: комментарий от stevejobs

OOP == BOP

Что-то я начинаю сомневаться в авторитетности источников, из которых ты узнал про LSP. Хотя дело, скорей всего, в неправильной интерпретации.

baverman ★★★
()
Ответ на: комментарий от stevejobs

LSP - это не проблема, это базовый принцип :3

Это становится проблемой, когда реализация его нарушает, очевидно же.

baverman ★★★
()

Можете поделиться, как разруливать такие ситуации с дублированием кода расово-верно? На примере того же эллипса и круга.

Это же даже на википедии разжевано?

baverman ★★★
()

если наследник не может реализовать какой-то метод (он не имеет для него смысла)

читай у Коплиена про анализ изменчивости (в частности, про отрицательную изменчивость)

jtootf ★★★★★
()

Я думаю lsp нужно свести к теории множеств, групп, теории категорий и т.д вверх по абстракции. Хотя, может jtootf даст комментарий?

anonymous
()
Ответ на: комментарий от jtootf

Ух ты, имеется в виду «Мультипарадигменное проектирование для C++. Библиотека программиста», заценю асап

stevejobs ★★★★☆
() автор топика

Во-первых используй где можно агрегацию вместо наследования. Во-вторых старайся по чаще использовать иммутабельные объекты. В-третьих это вообще проблемой особо не является. Например в жаве есть интерфес Collection. Представь, что в коде, использующем Collection я поменяю реализацию с ArrayList на HashSet. Тут не много другая проблема, правда. Нельзя безопасно менять реализации Collection, так как этот интерфейс нихрена не задает контракт, поэтому поведение полностью зависит от реализации. Тем не менее все нормально живут с этим Collection.

dizza ★★★★★
()

ITT ООП-петушары опять кудахчут про свои выдуманные проблемы.

В то время как GADT-БОГИ ржут над их никчемностью.

anonymous
()
Ответ на: комментарий от Sectoid

>>Теперь, есть классическая задачка, в которой круг нельзя наследовать от эллипса, потому что нарушается LSP

Нельзя, если объект мутабельный. Ежели нет — наследуйте на здоровье.

накоенц то. я пытался это доказать пару лет толпе(на sql.ru) а они кричали, а что если изменится сторона(там был квадрат прямоугольник) я им код на си++ писал, всеравно не понимали о чем я

anonymous
()
Ответ на: комментарий от anonymous

Уж не gadt-боги ли вводят новые сущности, когда не могут решить в алгебраических типах элементарные проблемы?

malbolge ★★
()
Ответ на: комментарий от malbolge

Элементарные проблемы решаются элементарно. Это тебе не костыли для выдуманных проблем ООП-фимозников.

anonymous
()
Ответ на: комментарий от anonymous

Да, элементарно решили - ввели в компилятор ghc понятие экзистенциальных типов, например :)
Так и на любом ЯП можно «элементарно» проблемы решать :)

malbolge ★★
()
Ответ на: комментарий от anonymous

>для выдуманных проблем ООП Тут ты частично прав.

malbolge ★★
()

Теперь, есть классическая задачка, в которой круг нельзя наследовать от эллипса, потому что нарушается LSP. Несмотря на то, что круг - частный случай эллипса.

Просто эллипс нужно наследовать от круга. Если класс «круг» содержит поле «радиус», то наследованный класс «эллипс» будет содержать поле «радиус» (вписанного или описанного круга), и «другой радиус» (большой или малый, соответсвенно).

quasimoto ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.