- 1
- 2
- 3
Тут недавно оказия вышла. В одном чатике, где были несколько программистов и математик, задали вопрос:
В каком порядке наследование верное целые числа -> рациональные или наоборот?
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+5
Тут недавно оказия вышла. В одном чатике, где были несколько программистов и математик, задали вопрос:
В каком порядке наследование верное целые числа -> рациональные или наоборот?
1) целые->рациональные
2) рациональные->целые
3)
целые->числа
рациональные->числа
4)
целые
рациональные
И ещё всякие модификации типа по интерфейсу на каждую операцию или интерфейс на все операции и и отдельный интерфейс на деление для рациональных
Ну и еще зависит от реализации ОО: можно ли удалять методы, заставляет ли язык сохранять те же типы / сужать / расширять типы методов.
Что-за чушь?
Ещё скажи:
5)
числа->целые
числа->рациональные
))
> числа->целые
Как будто что-то плохое.
При крестонаследовании потомок - это уточнённый вореант родителя.
Если к инту добавить ещё немного информации, будет плавающий питух (математически: если к инту добавить бесконечность знаков, будет риал).
У произвольного числа можно взять целую часть. А вот целое - недостаточно специально (наследование - специализация) для того, чтобы быть произвольным числом.
- оператор приведения Double к прямому предку (к Int), ибо стандартный в //1 тебе вернет 1, а не 1000
- оператор присваивания любого объекта в иерархии в Double (и тут, возможно, без шаблонной магии не обойтись) тебе надо попыхтеть и доделать:
ℕ ∈ ℤ ∈ ℚ ∈ ℝ ∈ ℂ
Именно это отношение наследование и выражает. Подкласс - это подмножество объектов базового класса.
Проблемы немедленно начинаютÑÑ, когда вводим клаÑÑ Ð½Ðµ ложащийÑÑ Ð² цепочку, например 𔸠∈ â„‚, но 𔸠∉ â„.
Или ð•€â„•, которое как â„• только мнимое.
ЕÑли Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾ понÑл, то ð•€â„• — Ñто натуральные чиÑла, домноженные на мнимую единицу? Тогда ÑвойÑтво «как â„• только мнимое» не работает, ибо в ð•€â„• не работает умножение: произведение двух мнимых чиÑел будет вещеÑтвенным чиÑлом.
Почему не работает. Метод должен вернуть целое.
Ð’ терминах ООП придётÑÑ Ð½Ð°Ð³Ð¾Ñ€Ð¾Ð´Ð¸Ñ‚ÑŒ кучу методов Ñ Ñвными типами. Больше типов => больше бойлерплейтных методов.
Видимо потому, что Ñто не ÑвойÑтво. Вроде не было утверждениÑ, что ещё и операции на Ñлементами ð•€â„• ведут ÑÐµÐ±Ñ Ñ‚Ð°Ðº же, как в â„•.
> в ð•€â„• не работает умножение
Ð’ â„• иногда не работает вычитание и деление, но Ñто не повод Ñчитать â„• нинужным.
Ð¥Ð¾Ñ‚Ñ Ð¾ чём Ñто Ñ? Седенионы не нужны, да и октавы тоже. Можно оÑтановитьÑÑ Ð½Ð° кватернионах.
Главное вÑÑ‘-таки, что тут нужно пиÑаÌÑ‚ÑŒ знак ⊂ (включение), а не ∈ (принадлежноÑÑ‚ÑŒ), потому что ℤ — Ñто множеÑтво чиÑел, а не множеÑтво множеÑтв.
https://clck.ru/9xmhy
Всё, что есть хорошего в ООП, на самом деле придумано ещё Дэвидом Парнасом.
Нужно писать на машинных кодах. Транслятор просто может не знать новые опкоды Вашего цпу
где гарантия что программист знает еще какой-нибудь язык?
Для математики или для лоу левела очевидно ООП плох. А для выражения, например, GUI отличен.
И для бизнес логики не плох.
О, я вспомнил годное применение ООП!
В STL тэги итераторов моделируются через наследование, чтобы выбирать в компайл-тайме оптимальную реализацию алгоритмов. google://tag+dispatching
И то надо было через компайл-тайм capability query сделать — не осилили.
Опять же, contiguous_iterator_tag не запихали в стандарт, потому что что-то у кого-то ломается. В общем там плохо.
Ну я и говорю, там по уму через проверку возможностей в компайл-тайме надо делать, и не заставлять программистов писать нинужные инкременты / экскременты там, где они не имеют смысла. Не является итератор регулярным? Просто не нужно реализовывать копирование (правда, без move-семантики тогда было бы трудновато). Если есть перегруженные скобки — значит, random access, если есть инкремент — значит, можно двигать вперёд, etc.
> forward_iterator это непременно inpit_iterator
В буст::итераторс нормально запилили. Там больше классов, все отделено и все это конвертится на всякий случай для убогого легаси интерфейса итераторов стл, если ими пользуется легаси код. Могли бы и в стандарт с++ внести вместе с этим конвертером
Вообще я могу намного большую херню сморозить например про органические соединения и их классификацию. Есть предельные, непредельные углеводороды, спирты, карбоновые кислоты, метал-органические соединения. Эта херня НЕ ОПИСЫВАЕТСЯ в рамках вашего ебучего наследования. Там можно только сделать какой-то блядский граф, который бы всю эту хренотень соедниял бы хитровыебанным образом. Так что говно этот ваш ООП
Короче, когда-то давно я начал выдумывать свой ПРИНЦИПИАЛЬНО НОВЫЙ ЯП чторы через графы, а не каким-то там ебнутым наследованием http://dump.bitcheese.net/files/ytykavi/test.svg вот это например, не обращайте внимание на опечатки и прочую хрень, я тут пытался как бы обобщения для сортировок сделать. Там еще много чего недописано, про всякие там проекции футамуры, специализации, суперкомпиляции, преобразованиями над графом программы, получение из графа зависимостей ярусно-параллельной формы, приделать ко всему этому какую-то систему символьных вычислений, короче хуйпоймичто
> Жаркая погода бывает редко, однако 13 августа 2003 года температура составила +37,0 °C, став самой высокой за всю историю метеонаблюдений.
В жаркой разве? По-моему, типичная температура для умеренного климата.
Ещё пишут, что на Украине поставили: http://pikabu.ru/story/_2002626
И в США тоже поставили: http://dagstadion.narod.ru/art183.html
И в Турции поставили...
А почему ты так о Шамиле беспокоишься?
>имперцы
АТО!
>фашисты
У фашистов главное - государство, так что да.
Нестыковка.
Целые через имплисит конструкторы Рациональных должен конвертиться в Рациональные. Рациональные через эксплисит оператор каста Рациональных должен конвертиться в целые. В таких условиях все дозволенности крестов с их кастами о наследовании можно не заботиться, хоть убирай вообще
>иначе мусор от реализации комплексных и вещественных чисел будет болтаться в интах...
Но как же? Наследование это ведь ОЧЕНЬ удобный и эффективный способ представления отношений между множествами и сучностями.
Именно по этой причине часто наследуют снизу вверх (от частного к общему), городят кучу виртуальных методов и наследование в жабном стиле (интерфейсами).
И вот на кодревью они чуть ли не драки у нас из-за этого устраивают.
>на кодревью они чуть ли не драки у нас из-за этого устраивают.
А вы, ребята, как ни наследитесь, в программисты всё-равно не годитесь.
Целочисленные синусы, косинусы и т. п. существуют?
Смысл в том, что в функцию Float sin(Float x) можно передать Integer, унаследованный от Float. Наследование не подразумевает, что внезапно появится функция Integer sin(Integer x).
>Наследование не подразумевает, что внезапно появится функция Integer sin(Integer x).
Как раз наоборот. Контрвореантность и ковореантность.
Наследование допускает сужение return-типа. Но не расширение, то есть мы можем сделать так, зная что не выйдем за пределы целых:
Integer add(Integer b)
При этом в паренте будет: Ratio add(Ratio b)
Но не допускает сужение аргумента. Т.к. если Integer extends Ratio то он тоже должен поддерживать
Ratio add(Ratio b)
но может быть реализован как
Integer add(Ratio b)
ибо Integer - подмножество Ratio.
>Ratio add(Ratio b); // для совместимости с родителем
Причём такой метод вовсе не обязательно делать. Он уже есть в родителе родителя. Достаточно реализовать какой-нить общий toComplex/toRatio и сразу появляются add/sub/mul/div, etc
Upd: борманд выше показал, что в джави можно так же.
http://coliru.stacked-crooked.com/a/188ea7ad76c9a108
(мультиметоды в кресты ведь так и не завезли?)
http://coliru.stacked-crooked.com/a/7f7d11994da28f91
я просто хочу хорошее сложение
Сложил 2 инта - получил инт. Сложил флоат (который мог быть как целым так и дробным) и инт - получил флоат и т.п.
В общем-то да. Тогда можно даже не делать их интерфейсами и не порождать их друг от друга, а просто дать Integer'у операторы каста в Ratio и Float, Ratio оператор каста во Float и т.п.
И если мы складываем 2 разных типа, один из них просто апкастнется во второй (что в общем-то и происходит с обычными int и float)...
Это и не работает :)
Эта проблема стара и убога как само ООП
Ааа, надо внести это в золотой фонд цитат
Some authors have suggested reversing the relationship between circle and ellipse, on the grounds that an ellipse is a circle with more abilities. Unfortunately, ellipses fail to satisfy many of the invariants of circles; if Circle has a method radius, Ellipse must now provide it, too.
Как его ни крути, всюду говно.
>>Число.
>>Мутабельное.
>>>Атомарная херь
>>>Мутабельная.
До такого дна наверное даже не все оопшные крестухи додумаются. И там где число, там же обычно и хеш-код рядом.
Так о чём и речь. Уже даже крестобляди не оптимизируют на мутабельных спичках шишках. std::move, все дела.
Остались только Цари.
Наверное ты хотел сказать)))) :
Float sin(Float* x) можно передать Integer* ну или хотябы const ...&
Ну и это плюсодетали, а там речь про наследование вообще.