LINUX.ORG.RU
Ответ на: комментарий от no-such-file

А как из этой функции теперь вызывать thisThing из Base?

Ты лучше скажи, как ты сможешь унаследовать A и B от Base, но не унаследовать thisThing. Если уж он там есть.

То есть в итоге у тебя все классы, и родитель, и потомки имеют метод thisThing. Можно писать функцию, принимающую Base и надеяться, что все будет хорошо.

И то, что он в A и C не работает как надо, есть нарушение LSP, за которое тебе придется пространно извиняться в документации %)

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 2)
Ответ на: комментарий от monk

Если у тебя несколько классов имеют общий метод, этот метод надо определять в интерфейсе или общем предке этих подклассов

Отлично, теперь эта иерархия внутри себя не нарушает LSP.

алгоритмы, которые могут использовать этот метод будут указывать в качестве типа этот интерфейс или общий предок с методом

И не смогут обращаться к методам из другого базового класса.

no-such-file ★★★★★
()
Ответ на: комментарий от Nervous

все классы, и родитель, и потомки имеют метод thisThing

Имеют, но ты же пишешь функцию на ThatThingBase, а он не имеет thisThing. Поэтому компилятор не даст её использовать. Потому что нет никакой гарантии что ThatThingBase объект одновременно ещё и Base.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

но ты же пишешь функцию на ThatThingBase

Мы ведь уже выяснили, что ThatThingBase нам ненужно, потому что thatThing есть у Base. Значит, будем писать функцию, принимающую Base, и все дела. И она (предположительно) будет невозбранно принимать потомков вместо родителя.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Nervous

Значит, будем писать функцию, принимающую Base, и все дела

Но тогда «принимающий код» как я и говорил раньше обязан будет проверять какой конкретно объект передан, есть там thatThing или нет. Нарушение LSP, кастование и тормоза.

no-such-file ★★★★★
()
Ответ на: комментарий от t184256

Ну короче принцип - просто совет, причем который в основном касается типов. Иначе зачем делать подкласс если он ведет себя как родитель вообще? Так что дело не в поведении

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от no-such-file

И не смогут обращаться к методам из другого базового класса.

Естественно. Ведь они (по твоему заявлению) обращается к функциям из базового класса, а их не может быть в другом базовом классе.

И смысла методы другого базового класса для объектов, которые унаследованы от этого (а не другого) базового класса, смысла иметь не могут.

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

готовь следующий акк, этому недолго осталось

99% гарантии что это очередной приступ у нашего пациента, а ему еще даже отвечают... Грустно, ЛОР

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от vertexua

может в методе walk() отформатировать вам винт. Это будет нарушение принципа, его идеи

Зависит от контекста. Если мы не о философских категориях говорим, а о типах в языке программирования, то нарушения принципа тут нет.

лишь помощь программисту

Да это помощь программисту, чтобы сделать формально корректную иерархию типов. При чём тут форматирование винта?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Что-то вы запутались, похоже.

есть Base, и наследники A,B,C,D. Из них C и D имеют новый метод thatThing(). Нужно написать функцию, которая работает только с C и D

Делаешь интерфейс thatThing. Если функция работает только с методом thatThing(), значит его в качестве типа аргумента и требуешь, если функция работает с thatThing() и методами Base, тогда создаёшь абстрактный класс thatThingBase, унаследованный от Base и реализующий интерфейс thatThing(). C и D наследники thatThingBase. Функция в качестве аргумента требует thatThingBase.

monk ★★★★★
()
Ответ на: комментарий от no-such-file

Но тогда «принимающий код» как я и говорил раньше обязан будет проверять какой конкретно объект передан, есть там thatThing или нет. Нарушение LSP, кастование и тормоза.

Как его может не быть в наследнике Base (в котором thatThing есть), я что-то не догоняю. Это какая-то мощная крестовая магия?

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

Liskov substitution

это про то, как спп заменяет лисп. что не ясно?

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

Прелесть принципа в том, что он не совет, а чёткая и дельная формализованная мысль. Суть в том, что настоящее наследование интерфейса влечёт за собой выполнение контракта до полной взаимозаменяемости. Неполное соблюдение контракта? Значит это не наследование интерфейса. Мутабельный квадрат - не мутабельный прямоугольник.

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

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

РавнобедренныйТреугольник

Ты можешь засетать разные длины сторон для равнобедренного треугольника? А для треугольника можешь. Всё приехали.

ya-betmen ★★★★★
()
Ответ на: комментарий от no-such-file

Ты в наследнике можешь в принципе добавить публичный метод, которого в базовом классе нет. Вот это по Лисков - плохо.

Пятизвёздочный СПВ as is.

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

Ты можешь засетать разные длины сторон для равнобедренного треугольника? А для треугольника можешь. Всё приехали.

Функция, ожидающая ПлоскаяФигура, даже не знает, сколько у нее сторон.

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

Функция, ожидающая ПлоскаяФигура, даже не знает, сколько у нее сторон.

Ты писал:

его потомка Треугольник или потомка потомка РавнобедренныйТреугольник

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

А для птиц и рептилий отдельные Бегуны?

interface Бегун:

abstract class МлекопитающееБегун extends Млекопитающее implements Бегун;

abstract class РептилияБегун extends Рептилия implements Бегун;
monk ★★★★★
()
Ответ на: комментарий от Nervous

Бегуны отличаются по количеству ног, их устройству и так далее, одни свойства зависят от других, так что используя композицию ты в итоге всё равно получишь несколько интерфейсов для бегунов. Бегун букашка слишком сильно отличается от бегуна жирафа. Если ты захочешь реализовать все виды на земле, тебе проще юзать иерархию. Меньше ада получится. Иначе одни свойства притянут другие и млекопитающие в тебя будут не только с клювами и яйца нести, но ещё и хвост начнут отбрасывать и плести паутину.

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

Ты писал:

его потомка Треугольник или потомка потомка РавнобедренныйТреугольник

So what? Функция, ожидающая плоскую фигуру, с радостью примет и треугольник, и равнобедренный треугольник (подклассы плоской фигуры). И вызовет на них какие-нибудь общеплоскофигурные методы. Площадь там.

Про специфические методы равнобедренного треугольника она знать не может -> вызывать их не будет.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

используя композицию ты в итоге всё равно получишь несколько интерфейсов для бегунов

Пащиму? Один интерфейс Бегун, все, кто бегает, его реализуют. Кто не бегает — не реализуют. То же самое с любым другим свойством.

Если ты захочешь реализовать все виды на земле, тебе проще юзать иерархию.

Боюсь, что одной иерархией на все случаи жизни тут не обойтись.

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

Функция, ожидающая плоскую фигуру, с радостью примет и треугольник, и равнобедренный треугольник

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

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

Все по-разному бегают.

Это нормально и может быть в одном интерфейсе. Называется полиморфизм.

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

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

Зависит от реализации, наверное.

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

У тебя они в вакууме, видимо, бегают. В реальности разница имеет значение.

Класс «сессия на беговой дорожке», инициализируем её бегуном индийским слоном, получаем какой-нибудь ад.

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 2)
Ответ на: комментарий от WitcherGeralt

Класс «сессия на беговой дорожке», инициализируем её бегуном индийским слоном, получаем какой-нибудь ад.

Надо габариты и массу проверять же, кроме соответствия интерфейсу %)

P.S. Ахтунг, трекер разворотило!

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 2)
Ответ на: комментарий от Nervous

И скорость бега ещё. Например, скорость бегуна черепахи будет ниже минимальной скорости дорожки. В итоге ты вместо нормальной системы типов получаешь сплошные проверки в рантайме.

WitcherGeralt ★★
()
Последнее исправление: WitcherGeralt (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

В итоге ты вместо нормальной системы типов получаешь сплошные проверки в рантайме.

Так все равно бОльшую часть ограничений придется проверять в рантайме. Возраст — целое число, окей. Это система типов может. А что это число неотрицательное? И больше 18?

Возможно, иногда проще добавить один предикат, где он реально нужен, чем принудительно и повсеместно ублажать систему типов? %)

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от Nervous

А что это число неотрицательное?

uint?

И больше 18?

Дорожка 18+? Типа как с ослом и морковкой, только морковка сзади, не будешь успевать, получишь мотивации.

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

морковка сзади, не будешь успевать, получишь мотивации.

А потом будем удивляться, что у нас зайцы задом наперед бегают.

Nervous ★★★★★
()

Это про что?

Это про языки с приличными системами типов. Суть принципа - отношение «тип B является подтипом A» означает, что все операции, выполнимые над A, также выполнимы над B с соблюдением всех законов (предусловий, постусловий и инвариантов).

Зачем это нужно в С++?

В самом C++ это не нужно - система типов там наглухо отбита, обмазана шаблонами и присыпана сюрпризами из C, так что можно делать всё, что угодно, всё равно получишь UB.

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

Так все равно бОльшую часть ограничений придется проверять в рантайме. Возраст — целое число, окей. Это система типов может. А что это число неотрицательное? И больше 18?

Все ограничения придётся проверять в рантайме, потому что в рантайме имеем дело с сырыми байтами. А вот дальше система типов может заставить нас проверить, что это число целое, неотрицательное, больше 18, меньше 65, и отлупить по рукам, если этих проверок не было. Зато когда в сигнатуре функции написано «Целое от 18 до 65», можно быть уверенным, что это так.

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

дальше система типов может заставить нас проверить

Ну я статическую имел в виду. Чтобы все на этапе компиляции проверялось, как тут любят.

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

Так я тоже про нёе. Если вы не проверите, что число лежит в указанном диапазоне, то программа не скомпилируется.

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

Если вы не проверите, что число лежит в указанном диапазоне, то программа не скомпилируется.

Круто. А в жабе, к примеру, так можно?

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

В самом C++ это не нужно

... тем кто на нем не пишет.

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

Привожу пример есть класс «млекопитающие» - все наследники получают умение дышать, есть, издавать звуки, размножаться и т.д.

Какое же говно это ваше ООП. Развиваешь предмету дальше, вводишь «пол» и всё ломается. Вводишь ампутации и всё ломается еще раз. Вводишь протезы и идешь все переписывать.

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

Ууууу.

abstract class МлекопитающееБегунПивунБлювунХрапун........
.........
.........etc extends Млекопитающее implements Бегун, Пивун, Блювун, Храпун, ..., ..., ..., etc;
facepalm.jpg

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

А в жабе, к примеру, так можно?

В самой жаве нет, а вот в скале, целящейся в jvm, что-то есть, так что ынтырпрайз уже может получать профит от надёжного кода. А так, гуглить по словам dependent types, рано или поздно оно докатится и до массового потребителя.

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

dependent types, рано или поздно оно докатится и до массового потребителя

Почитал, выглядит неплохо, но

  • сложна
  • не всегда работает

Для учоных, наверное, норм %)

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

abstract class МлекопитающееБегунПивунБлювунХрапун…

abstract class Алкаш extends Млекопитающее implements Бегун, Пивун, Блювун, Храпун, ...

Починил.

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

Кстати, где будет реализация «Бегун»? В каждом классе из кучи алкашей? Ладно в плюсах можно сделать множественное насделование, но как это всё будет бегать, например, на костылях? Новой реализацией наследуемой от «Бегуна»? И как это потом всё это на ходу инжектить, менять и делать рефлексю?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.