GraphQL у свiтi компонентiв від Катерини Поршнєвої — React fwdays онлайн | 27 березня
×Закрыть

Java-программисты и некрофилы, что общего и как сказать наследованию «Хватит»

Просматривая попытки объяснить сущность ООП наконец понял что меня в нем смущало. Итак, Java как яркий представитель языка с ООП лучше всего описывает абстрактные объекты, которые никогда не существовали в реальном мире. Описать им реальные сущности намного сложнее и в этом ООПисты заимствуют опыт некрофилов. Те предпочитают иметь контакт с неподвижными объектами. Мертвый объект — хороший объект. Также объект можно надежно связать и тогда он не сможет сопротивляться попыткам запрограммировать его на Java или на Python.

Следствия этого — Java лучше всего прижилась на серверах(моргах), где занимается обработкой новых и уже существующих партий трупов. Программисты на Java получают больше всего мертвых американских президентов, что можно увидеть по статистике доу. Подобное липнет к подобному. Оракловские базы данных, конечно же, лучше всего описывают трупы сотрудников. Такие сотрудники никогда не напишут свой комент на доу и тем более их никогда не вытащишь попить пива в ближайшей забегаловке или просто на воздухе

Из этого же следует абсолютная беспомощность учебников которые пытаются объяснить ООП на примере живых сущностей. первой ссылкой по запросу «java наследование» гугль выдает страницу с таким кодом

package ru.alexanderklimov.quickcourse;

public class Animal {

String sleep(){
return "Животные иногда спят";
}
}

public class Cat extends Animal {

}

надеюсь не нужно пояснять, что приведенный класс описывает чучело кота. живой кот быстро Вас поцарапает при попытке описать его таким бредом и не согласится быть абстрактным животным. Кроме того, понятно, что абстрактное животное никогда не существовало. природа всегда развивается и коты были потомками вполне конкретных живых сущностей. По факту, все классы в Java являются абстрактными и поэтому модификатор abstract бессмыслен. Лучше говорить, что некоторые классы описывают не совсем мертвые сущности и им приписать модификатор notdead.
Термин и понятие наследования также является абсолютно некорректным, этот момент уже обсуждался на доу.

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

class HeavyBox extends Box {
    int weight; // вес коробки
    
    // конструктор
    HeavyBox(int w, int h, int d, int m) {
        width = w;
        height = h;
        depth = d;
        weight = m; // масса
    }
}

коробка тут описывает искусственный объект созданный человеком(природа никогда бы не создала такой) и тут все идеально. Реальные объекты намного хуже и с кучей оговорок о чем нужно всегда предупреждать.

Приятной Вам возни с трупами классами

👍НравитсяПонравилось0
В избранноеВ избранном0
LinkedIn

Похожие топики

Лучшие комментарии пропустить

Сразу видно что автору системный анализ в университете не читали!

Код это модель предметной области. Модель это упрощенное представление реальности которое концентрируется на существенных деталях, отсекая несущественные/нерелеватные проблемы. В реальности тот же кот представляет собой очень сложную систему которую человек не может представить. Кот это млекопитающее обладающее сложной нервной системой, системами органов, поведением, психологией. У него есть днк которое состоит из сотен тысяч соединений аминокислот, соотвественно у кота есть обмен веществ, в котором участвуют тысячи разных белков, жиров, углеводов.
Но если ты пишешь приложение, то в твоей модели (соотвественно в коде) будут отображены только релевантные решаемой проблеме/сфере знаний ( domain ) аттрибуты кота. Например для интернет-зоомагазина, там будет достаточно породы, имени, цвета и цены. Соотвественно такая модель будет полезна для решения проблем с поиском и учетом котов в отдельно взятом приложении.

Можно смоделировать кота в терминах обьекта и поведения, а можно в виде категорий и функций. Но понять кота как обьект с аттрибутами и методами/сообщениями гораздо легче чем городить котофункторы, котоморфизмы и котомонады.

Однажды вечный джуниор пришёл к великому Алану Кею и пожаловался на то, что сущность ООП ускользает от его понимания, а все определения или слишком абстрактные или наоборот слишком примитивные.
Алан Кей отставил рюмку саке в сторону и долго осматривал свой дом чтобы найти то, что лучше всего поможет описать ООП.
В конце концов он нашёл старую бейсбольную биту и принялся колотить вечного джуниора и приговаривать — Объект это не утка, это обязательство вести себя так как ведут себя утки!
Контракты и обязательства! Инкапусляция, полиморфизм и наследование! Парадигма, а не программирование!
В конце концов он устал, бросил биту и спросил у лежавшего на полу вечного джуниора — Теперь ты понял что такое ООП?
— Хррр..эх..бл — ответил вечный джуниор и пополз к выходу.

Вам бы доктору показаться...

Гы. Белка у программиста в период новогоднего запоя ? :)

Мне кажется ты затронул очень серьезные философские проблемы. Как ты различаешь что именно живое, а что нет? И как абстрактное от неабстрактного? Общеe от частного? В конце концов сущность и явлениe?

Философы особенно настойчиво пытались понять степень расщепленности сущности и явления и характер их соотношения друг с другом. Гегель подчеркивал единство сущности и явления. Сущность является, явление существенно. У Гегеля сущность активна, она проявляется. Такое приписывание сущности качества активности вызывало многочисленные протесты. Диалектические материалисты (Маркс) и неопозитивисты относили свойство активности к единичным явлениям: друг на друга влияют элементарные частицы, животные, люди. Общее не влияет на единичное. Так, законы Ньютона не воздействуют на механические явления.

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

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Спасибо, поржал.
Но абстрактные классы конечно не надо использовать там, где можно их не использовать

Вам, батенька, с такими ассоциациями — к психиатру бы.

коробка тут описывает искусственный объект созданный человеком(природа никогда бы не создала такой) и тут все идеально.
Большинство приложений то же описывают объекты созданные человеком. Так что все ОК. Никогда не встречался с задачей запрограммировать живое существо.
А примерчики с «наследованием» кошечек — это для детей, что бы понятнее было. Если смущает — можно заменить на пример с геометрическими фигурами. Например наследование квадрата от прямоугольника: этот пример прекрасно показывает принцип замещения Лисков и проблему «отказа от наследства». И вообще: человек мыслит абстракциями. Когда один человек пишет «кот», а другой это читает то это именно абстрактный кот («мертвый» или «чучело»), а не вполне конкретный Мурзик из второго подъезда с надорванным ухом. А любой язык (программирования в том числе) — это описание абстракций. Так что никакой «некрофилии».

>>Например наследование квадрата от прямоугольника: этот пример прекрасно показывает...

...как не надо наследовать.

...как не надо наследовать.
Раскройте мысль, пожалуйста.

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

Ну, например, использование прямоугольника
rectangle.setWidth(10);
rectangle.setHeight(20);
rectangle.getPerimeter(); // 60

А что будет если сделать
square.setWidth(10);
square.setHeight(20);
square.getPerimeter(); // ???

Если у вас верно спроектирован квадрат, то внутри второго сеттера

square.setHeight(20);
должен вылететь IllegalArgumentException («width and height should be equal»), вы можете и должны переопределить методы базового класса, но верно. Периметр считается точно также.

Опять же даже здесь видно кривое применение наследования. У квадрата все стороны равны и ему не нужна ширина И высота, а достаточно одной длины стороны, но мы же от большого ума наследуем четырехугольник и теперь ССЗБ-ы и должны тащить телегу из одного ненужного метода и состояния за собой.

Почему именно внутри второго, а не первого? Почему исключение, а не установка ширины равной высоте? Почему у квадрата может быть только ширина, а не только высота? Вообще применимы ли эти оба понятия к квадрату?

Как раз потому что при вдумчивом разборе возникает множество вопросов, ответы на который весьма субъективны, наследование квадрата от прямоугольника является хорошим примером как не надо наследоваться в коде, базируясь на «очевидных» «наследованиях» (кстати, почему наследник прямоугольника, а не ромба? или может тут множественное наследование нужно?) в реальном мире.

В реальном мире наследования не существует, в том то и проблема. И абстрактных классов, объект которых нельзя создать не существует. То что живые организмы используют ДНК для создания своих не делает этот процесс наследованием в понятном программисту смысле.

Почему именно внутри второго, а не первого?
В обоих сеттерах надо проверять примерно так, второй throw можно заменить на IllegalStateException, но пока что некритично.
setWidth(int width) {
    checkConditions(this.height, width);
    this.width = width;
}

setHeight(int height) {
     checkConditions(this.width, height);
     this.height = height;
}

void checkConditions (int firstDimentsion, int secondDimension) throws illegalArgumentException {
      if (secondDimentsion <= 0) {
             throw new IllegalArgumentException("cannot create with not positive dimension");
      } else if (firstDimension > 0 && firstDimension != secondDimension) {
             throw new IllegalArgumentException("width and height should be equal");
      } else {
        return;
     }
} 
Почему исключение, а не установка ширины равной высоте?
Это нормальный fail first подход, потому что иначе вы никогда не найдете ошибку.

Все остальное сами виноваты раз тянем наследование.

В реальном мире наследования не существует, в том то и проблема
наследование — инструмент моделирования, а не познания. и тем более — не часть реальности.
в реальном мире атрибутов не существует.
и цифр.
всё абстракция.
всё тлен.

Как абстракция в человеческом мозгу оно существует, но не является строго детерминированным, мозг интуитивно замечает несоответствия «контрактов» предка и родителя и просто не пробует выполнять и/или проверять те из них, которые заведомо не соблюдаются и/или создаёт их на лету, вводя «методы» типа «установить одновременно ширину и высоту в одно значение». Если, конечно, нет намерения потроллить кого-то :) Формальной детерминированной системе же трудно «объяснить», что не всегда экземпляр класса наследника может заменить экземпляр класс родителя.

Ничего, что при таком подходе по сути setHeight и setWidth работать вообще не будут, что значения можно будет установить только в конструкторе или рефлексией, обходя проверки?

Эээ, ну да, нехорошо получилось, чем-то похоже на dead lock когда первый ждет второго, а второй — первого.

А давай немного изменим условия. Методы setHeight и setWidth — неправильные с точки зрения абстрагирования. Нужен один метод setEdgeLength("lengthPattern"), где lengthPattern — аналог css-свойства margin (можно указывать одно, два, три, или четыре значения). Тогда он хорошо подходит под ромб, квадрат, прямоугольник, трапецию и прочие извращения.

Но с одним параметром непонятно ромб или квадрат. Тогда уж просто задаем вершины или стороны как векторы. А чтобы различать квадраты и прочее, и удобно с ними работать, делаем врапперы в которые фигуры инжектятся и существуют методы типа isValid(). В общем типа:
Figure figure = new Figure([0,10], [10, 0], [0, −10], [-10,0]]);
Square square = new Square(figure);
if (square.isValid()) {
square.setSize(20);
square.getPerimeter(); //80
} else {
throw ’Not a square’;
}

Как это непонятно? Вполне логично, что без указания угла между сторонами a/b будет именно квадрат.
setEdgeLength("100/30") - ромб с углом 30 градусов между сторонами a/b, равными 100 единицам

А что будет если сделать
square.setWidth(10);
square.setHeight(20);
square.getPerimeter(); // ???
Тут дело не в наследовании, а в дизайне.
Я бы или бросал исключение в одном из методов, что указало бы на ошибку в использовании компонента. Или же можно тихо пересетить, то есть square.getPerimeter() == 80.
В любом случае просто надо читать спеку.
.
Момент № 2: Сеттеры и геттеры — это не обязательное свойство ООП-решения. То есть вполне можно так:
new Rectangle(10, 20);
new Square(20);
А метод #getPerimeter() переопределяется у наследника.
.
Момент № 3: Квадрат и прямоугольник обычно дают с вопросом «Что должно от чего наследоваться?». Так что в некоторых архитектурах может не быть второго метода.
.
Вариатн № 4: Можно таки не использовать наследование.
.
Я так понимаю, эти варианты и имелись ввиду:
этот пример прекрасно показывает принцип замещения Лисков и проблему «отказа от наследства»

Нет, не так. Квадрат никак не расширяет функциональность прямоугольника, он всего лишь один из его частных случаев.
Поэтому нет никакого смысла городить отдельного потомка.

С одной стороны он один из частных случаев прямоугольника, но с другой стороны он так же частный случай ромба. Но прямоугольник и ромб обладают в целом взаимоисключающими свойствами, поэтому квадрат должен реализовывать только пересечение контрактов своих «родителей», а не объединение как это обычно бывает при множественном наследовании.

А еще это проекция куба и пирамиды, например.
Но и это также плохо объясняет зачем нужно наследование для частного случая того же объекта без дополнительных свойств.
Мое обоснование проще, хотя ваше тоже вполне верное, конечно.

Ну раз уж такой простой пример с геометрическими фигурами вызвал столько полемики то предложу свое решение.
И оно вполне очевидное: при проектировании нельзя думать о наследовании реализации (да и о реализации вообще), а только о наследовании интерфейсов (чистые абстракции)!
Как правильно сказали: квадрат это и прямоугольник, и ромб, и параллелограмм, но в полной мере ни то, ни другое ни третье. В общем такое можно сказать про большинство объектов: они могут вести себя по-разному в разных условиях.
Именно поэтому как только мы унаследовали поведение — у нас начинаются проблемы «перекрыть», «валидировать», «вызывать в правильном порядке» и т.д. И кто-то кричит «наследование — зло», а ООП — отстой.
А зачем мы вообще что-то наследуем? Всего лишь для того, что бы одинаково работать с объектами! У нас ведь нет цели описать объект максимально полно! Если мы работаем с ромбами: то квадрат вполне сойдет за ромб. И за прямоугольник сойдет если работаем с прямоугольниками. А самое главное: поведение одного и того-же метода в разных интерфейсах может отличаться!
Наследование в ООП не значит что утка может родить курицу. Оно просто значит что и те и другие могут летать. И бабочки в эту иерархию то же подходят. И нам пофиг на природу и реальную жизнь: ведь наша задача — это не забыть построить крышу, что бы не улетели.

Интересный жизненный урок, который можно извлечь из комментариев к этой статье — работа программистом (и вообще в IT) не гарантирует никакого open-mindedness в голове.

Вроде бы креативный класс, доступ к интернету, работа с новыми технологиями — а вместо попытки прочитать нешаблонную статью на несчастных полторы страницы и найти там среди стёба здравую мысль — комментарии сводятся к «что курил», «почём грибы», «где такую траву брал», и, кажется, вот-вот перейдёт в стадию классического «как я встретил маму автора».

Ну что ж, полезный вывод на будущее. А с автором бы выпил пива при случае — явно будет о чём поговорить.

Вроде бы креативный класс, доступ к интернету, работа с новыми технологиями — а вместо попытки прочитать нешаблонную статью
Тут как раз «креатиФФная», а не «креативная».
Если есть что сказать (без относительно ТСа), то эффективнее сказать это прямо.
не гарантирует никакого open-mindedness в голове.
А какие тут новые идеи? Вот вы что нового увидели в статье? (Мне интересно что я пропустил)

В интернете слишком много говна, чтобы в каждом копаться, искать «а может там что-то есть». А негодование возникает от того, что на Доу я прихожу за вменяемыми статьями, именно чтобы не переваривать тонны бессмысленного шума с других сайтов. Для тупого стёба есть специализированные помойки.
Ну и конструктивно — в статье пообсирали подход, а ничего не предложили. Говно статья, потерял время.

и найти там среди стёба здравую мысль

Потому что в статье всё новое не существенно, а всё существенное не ново. «Здравая мысль» сводится к тому, что модели — это не реальный мир. Ну так это говорят на профильных специальностях не позже 4-го курса, а часто и раньше.

Ну что ж, полезный вывод на будущее.

О том, что статьи уровня для школоты будут обкомментарены со всех сторон? Jawohl.

Gracias, amigo за поддержку. правда я не понял почему топик назвали статьей. я сделал обычный пост для обсудить накипевшее. и никому не обещал в нем кристально чистого конструктивизма, и уже узнал много нового :)

Воинствующий жаваскриптер что ли? Все выше сказанное подтверждает лишь поговорку " с дуру можно и х... сломать".

Поток сознания, бессмысленный и беспощадный

Уважаемый а что вы таки думаете по поводу композиции?)

пока что ничего не могу сказать на эту тему

Итак, продолжаем серию образовательных видео по основам программирования. Нам продолжают приходить письма со всех уголков СССР и есть один вопрос, который задают чаще других: «Что такое статические переменные?». У многих возникают затруднения с этой темой. Так вот, наши мертвые слушатели, давайте же посмотрим урывок из «Самого лучшего фильма» про общую повариху. Что же мы видим? Солдаты — экземпляры класса Боец и у всех есть доступ к статическому полю Белоснежка. Белоснежка — экземпляр класса Повариха. Поскольку она статическая, то она общая для всех экземпляров класса Боец.
Всем некрофилии, ждем ваших писем.

vk.com/...11528_160279877

Еретики! на костер, пусть используют только камни! и блоки ! не каких животных пусть отпустят и не мучают!

Автор этой статьи и новогодние праздники, что общего и как сказать алкоголю «Хватит».

может его доктора отпустили, или «нечто»

На костер еретиков!!! Используют животных!!!

Гугл по словам- java наследование — не выдает то что Вы написали. А так да... смешно... с огоньком...

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

Что за бред я только что прочитал? Впрочем, я всегда подозревал за явой что-то неладное

Гы. Белка у программиста в период новогоднего запоя ? :)

Тема трупів розкривалась непогано, але автор чомусь швиденько зіскочив із такої багатообіцяючої теми на ООП і Java.

Одразу згадалося запитання на хабрі, як в ООП правильно нагодувати песика людиною... :)

Це запитання розкрило мені очі на деякі аспекти цього підходу, та з тих пір в мене викрісталізувалася довольно дивна думка.

в ООП правильно нагодувати песика людиною
Publish-subscribe. Человек инициирует евент — НакормитьСобаку, пес его обрабатывает.

В реальному житті все не так. Людина майже ніколи не годує песика. Зазвичай є два незалежні процеси: накладання їжі в миску та споживання їжі собакою. При чому вони можуть бути взагалі не пов’язані між собою. Собака може знайти собі їдло самостійно. Собака може ініціювати процес наповнення миски, подавши сигнал «Хазяїн, їсти хочу», але не факт, що він буде оброблений, та ще й невідомо ким.

Вы работали с JMS? Там тоже producer и consumer разные сущности и взаимодействие между ними производится посредством самого JMS, в реальном случае JMS заменяется миской с кормом / продвинутой авто-кормилкой с таймером или женой, которая покормит собаку вместо вас.

Не працював саме з JMS, але дуже полюбляю подійно-орієнтоване программування. Навіть в HTML/JS його переніс

Мне кажется ты затронул очень серьезные философские проблемы. Как ты различаешь что именно живое, а что нет? И как абстрактное от неабстрактного? Общеe от частного? В конце концов сущность и явлениe?

Философы особенно настойчиво пытались понять степень расщепленности сущности и явления и характер их соотношения друг с другом. Гегель подчеркивал единство сущности и явления. Сущность является, явление существенно. У Гегеля сущность активна, она проявляется. Такое приписывание сущности качества активности вызывало многочисленные протесты. Диалектические материалисты (Маркс) и неопозитивисты относили свойство активности к единичным явлениям: друг на друга влияют элементарные частицы, животные, люди. Общее не влияет на единичное. Так, законы Ньютона не воздействуют на механические явления.

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

Сразу видно что автору системный анализ в университете не читали!

Код это модель предметной области. Модель это упрощенное представление реальности которое концентрируется на существенных деталях, отсекая несущественные/нерелеватные проблемы. В реальности тот же кот представляет собой очень сложную систему которую человек не может представить. Кот это млекопитающее обладающее сложной нервной системой, системами органов, поведением, психологией. У него есть днк которое состоит из сотен тысяч соединений аминокислот, соотвественно у кота есть обмен веществ, в котором участвуют тысячи разных белков, жиров, углеводов.
Но если ты пишешь приложение, то в твоей модели (соотвественно в коде) будут отображены только релевантные решаемой проблеме/сфере знаний ( domain ) аттрибуты кота. Например для интернет-зоомагазина, там будет достаточно породы, имени, цвета и цены. Соотвественно такая модель будет полезна для решения проблем с поиском и учетом котов в отдельно взятом приложении.

Можно смоделировать кота в терминах обьекта и поведения, а можно в виде категорий и функций. Но понять кота как обьект с аттрибутами и методами/сообщениями гораздо легче чем городить котофункторы, котоморфизмы и котомонады.

верно. не имел возможности ознакомиться

Однажды вечный джуниор пришёл к великому Алану Кею и пожаловался на то, что сущность ООП ускользает от его понимания, а все определения или слишком абстрактные или наоборот слишком примитивные.
Алан Кей отставил рюмку саке в сторону и долго осматривал свой дом чтобы найти то, что лучше всего поможет описать ООП.
В конце концов он нашёл старую бейсбольную биту и принялся колотить вечного джуниора и приговаривать — Объект это не утка, это обязательство вести себя так как ведут себя утки!
Контракты и обязательства! Инкапусляция, полиморфизм и наследование! Парадигма, а не программирование!
В конце концов он устал, бросил биту и спросил у лежавшего на полу вечного джуниора — Теперь ты понял что такое ООП?
— Хррр..эх..бл — ответил вечный джуниор и пополз к выходу.

Він ніколи так не стане програмістом.

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

public class MyOwnLunaPark extends LunaPark{
public Feature блэкджэк;
public Feature шлюхи;
}

Java умеет юникод в именах, так что

public List<feature> шлюхи;
вполне подойдет. А вот если оборачивать в геттеры-сеттеры, то будет не сильно красиво:

public List<feature> getШлюхи() { ... }

Java умеет юникод в именах, так что
Ого, никогда такая идея в голову не приходила

Это видимо не приходилось видеть переменные и каменты на хинди.

раз умеет юникод, то и геттер уже будет

public List<feature> подайтеШлюх() {}

я много раз рассказывал историю про французов, которые вместо isActive писали estActive и потом удивлялись, почему всякие инструменты и библиотеки их геттеров не видят.

И да, тут

notdead
Правильнее использовать модификатор undead.

Чувак, ты эту всю фигню брось, лучше поделись травой.

Думаю вброс долго не продержится, ибо большинство в отпусках

Классно Говоришь — Автор Молодец.

Беда всех этих учебников в том, что они учат ООП/наследование по какому-то конкретному языку, который, вероятно, далеко не лучшая, не чистая и тем более не единственно возможная его реализация.
Java еще ладно, когда я слышу от студней-джунов что-то в духе «использовать ООП» в значении «использовать виртуальные функции C++» мне хочется убивать.

что они учат ООП/наследование по какому-то конкретному языку
В общем согласен.
Как по мне, то тот факт что учат по конкретному языку не есть большая проблема. А вот то что начинают с наследования и вбивают сказку про 3 кита — это уже дает очень негативные последствия.
Еще один неприятный момент, почему-то мутирование объекта, часто, преподносится как очень важная фича ООП-подхода.

Три кита — это тоже ненависть-ненависть-ненависть.

Беда всех учебников в том, что в обучении нарушена причинно-следственная связь. В реальности вы сначала сталкиваетесь с проблемой, а потом находите решение. В обучении — вам сначала рассказывают решение, а потом показывают(притягивают за уши) проблемы, которые можно решать. В результате, все это больше похоже на фарс, чем на реальную жизнь.

А самая пичалька начинается, когда этот фарс пытаются впихнуть в реальный проект.

Не имел с ним делов. А вот Objective-C, про который говорят, что является идейным наследником, — прекрасен.
Но дело не в конкретном языке. Лучше бы просто объясняли о том, что такое ООП подход, какие методы применяются, а потом как уже это реализуется в конкретных языках, какие есть сходства, какие различия. И показыли примеры на разных.

Жаль, топик нельзя лайкнуть.

По теме — очень нравится модель прототипного наследования, как в JS. По крайней мере, для описания domain-specific-логики она подходит куда лучше классического наследования.

А можно пример как у тебя классно получилось задизайнить сущность с прототипом, и ты потерпел фиаско с ООП?

хохо, еще остались люди, которые считают прототипно-ориентированное наследование «недостаточно ООП»!

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

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

Так это я интересуюсь есть ли что-то такое или прототипное наследование никаких плюсов не имеет.

Та фигня то ООП, главное динамическая типизация :)

По моему опыту в подавляющем большинстве случаев динамическая типизация сводится к автоматическому выводу типов при инициализации или используется нестрогость типизации, когда в переменную то 100500 идёт, то ’100500′

Хуже, когда 067 молча превращается в 67, когда имелся в виду телефонный префикс.

067 — неправильний телефонний префікс, бо код України +380, не +38

Я предполагал, что кто-то начнёт придалбываться к столбу вместо того, чтобы хотя бы немного подумать.
Отвечаю: если речь идёт о правилах приземления раутинга по виду
select {
/^38044/ => none
/^38067/ => check_perm(1) && prefix(067)
/^380/ => check_perm(2) && prefix(0)
/.*/ => check_perm(3) && prefix(00)
}

это префикс, что бы вы там себе ни возомнили.

Національна комісія, що здійснює державне регулювання у сфері зв`язку та інформатизації, притримується думки, що префікс — 67
www.nkrzi.gov.ua/...2&language=uk#2

:) Я розумію, що сперечатися з тобою марна справа, бо ти ще 10 років тому займався практичною стороною телекомунікацій, та ще й на низькому рівні... Нам навіть довелося трохи попрацювати разом, але я більше люблю не практичну, а теоретичну сторону.

Справа не в тому, що собі думає комісія, що кому де «теоретично», і так далі. Нарешті, чому Ві вирішили, що мова про Україну? Десь у іншій країні теж може бути 067 :)
«Теоретична» сторона у даному питанні тільки одна: 0 відрізався, бо щось вирішило, якщо схоже на число, то число. Все інше — нецікаве.

Я розумію, що сперечатися з тобою марна справа,
У даному випадку — саме так. Чому — див. вище.

Мені стало цікаво, яка мова програмування дозволяє 067 зберігати саме як число 067, а не строку «067»?

Не знаю, яка, і не казав нічого про такі мови.

Та запитання до вельмишановного панства більш...

или когда 2 / 3 * 3 превращается в 1.99999998
или когда запись за пределами выделенной памяти
или когда BSOD

Ничего из этого не связано с динамической или нестрогой типизацией.

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

когда 067 молча превращается в 67
?
а я-то думал, здесь просто делятся наболевшим.

но в соответствующих ветках:)

а как можно получить кейс

когда 067 молча превращается в 67

?

Отдали правила раутинга из процесса на Perl на экспорт в YAML...

окей. это задача.
а вот, откуда появилось преобразование «067» в число, если речь об экспорте в YAML?
то есть, синтетическую «проблему» я могу придумать и сам: «067» — 4, но, очевидно, надо быть упоротым, чтоб предполагать любое поведение на нетипичном для строк операторе.
вот, мне и интересно, что ж там такого случилось?

&& prefix(067)
правильно ли я понимаю, что некий код на Perl, вытаскивал строку из текстового конфига и работал с 067 как с числом?
если так, то мне хочется понять — как же так вышло? я ж так понимаю, вы колупались в этой проблеме.
а вот, откуда появилось преобразование «067» в число, если речь об экспорте в YAML?

Ни одно стандартное средство Perl без хакерского залезания на уровень формата в памяти не позволяло и не позволяет и сейчас определить по скаляру, он содержит число или строку, представляющую число.
Вот относительно свежее подтверждение (Devel::Peek это уже грубое и дорогое хакерство).

Соответственно, дампер пытался это выяснить сам — если получалось понять как число, выдавал число, иначе — строку.

В этом Perl кошмарнее даже Javascript — в последнем хоть typeof рассказывает, какой тип значения.

Проблема была решена опцией дампера — передавать все скаляры как строки. При этом числа тоже передавались как строки, но это нас там устроило (приёмник на Python конвертировал сам).

Конфиг выглядел как список элементов, каждый из которых представлял собой список из префикса и описания правил, которые применяются при этом префиксе. При передаче без ключа always_strings (точного названия не помню) префиксы типа 091 становились просто 91...
(и, упреждая, это не украинские NDC — это e.164, где 0 значит частное пространство номеров, то есть ломался раутинг собственных номеров PBX)

Таки перейшли на пітон? Не пройшло і 10 років :)

Ніхто не переходив. b2bua був на Пітоні з самого початку.

окей. спасибо за подробности.
попробовал
use Data::Dumper; print Dumper('001');
получил «$VAR1 = ’001’»
или речь о парсинге?
ПС в Перле ничего не смыслю. хочется офигеть.

хочется офигеть.

По основной работе не хватает? ;)

use Data::Dumper

Dumper это хакерство:) потому что он сначала превратит в текст, а потом можно будет проанализировать, что же это было, по выведенному. Это долго и криво.

Я имел в виду вот что.
Берём питоновый вариант:


>>> print yaml.dump(123)
123
...

>>> print yaml.dump("123")
'123'

>>> print yaml.dump([123, "456"])
[123, '456']

>>> print yaml.dump(["123", 456])
['123', 456]

А теперь рисуем для перла:


$ cat <a href="http://d1.pl" target="_blank">d1.pl</a>
#!/usr/bin/perl
use YAML::Dumper;
my $dumper = YAML::Dumper->new;
print $dumper->dump(123), "\n";
print $dumper->dump("123"), "\n";
print $dumper->dump([123, "456"]), "\n";
print $dumper->dump(["123", 456]), "\n";
$ perl <a href="http://d1.pl" target="_blank">d1.pl</a>
--- 123

--- 123

---
- 123
- 456

---
- 123
- 456

различие в форматировании вывода несущественно, а вот в игнорировании строкового характера части входа — очень.

Для сравнения, модуль для JSON уже поправили, он умеет различать виды скаляра — применено сверхсильное секретное колдунство B::svref_2object!


$ cat d2
#!/usr/bin/perl
use JSON;
print encode_json({'a' => 1, 'b' =>; '2'}), "\n";
$ perl d2 
{"a":1,"b":"2"}

я так понимаю, что YAML как формат вполне себе позволяет произвольные строки без кавычек выводить, верно?
то есть, проблема «096» -> 96 на самом деле заключена в парсере, так?

я так понимаю, что YAML как формат вполне себе позволяет произвольные строки без кавычек выводить, верно?

Он-то позволяет, но если тип данных явно может различаться, то пользоваться этой возможностью уже нельзя.
Заковыка именно в том, что принципиальное различие между числом и строкой устраняется с потерей принципиально важного фактора.

то есть, проблема «096» -> 96 на самом деле заключена в парсере, так?

Если этого нуля нет уже при дампе — то парсеру поздно что-то чинить.

Если этого нуля нет уже при дампе
ну, я это и выясняю у вас — при дампе или при парсинге :)
пробовал на ideone — а там нет пакета YAML

Тогда (~2003) — нуля не было. Пока не дали спец. ключ.
Сейчас не воспроизведётся — у современных версий пакета всегда этот ключ как бы установлен в «понимать всегда как строку», и на дампе, и на загрузке. Разве что поставите версии 11-летней давности.
Проблема не исчезла, её просто замаскировали :)

Можете расшифровать её преимущество? Кроме многословности?

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

Наследование в самом деле нужно применять крайне осмотрительно и осторожно, стараться не смешивать поведение и состояние при наследовании. Как только смешали — ловите проблемы с вероятностью 99%. Как правило проблемы с иерархией сущностей вызваны недостаткой экспертизы или отсутсвием senior-а/техлида, когда все идет на самотек и увидев 2-3 одинаковых метода они выносятся в base класс, вместо использования той же стратегии.

Чувак, жжошь.
Я аж залогинился на доу спустя полгода, чтобы написать тебе «Пиши исчо!».
Отдельно спасибо за котэ.

P.S. Сам некроморфю на Java; пусть метнет камень, кто без греха.

Я бы посоветовал смотреть на срок годности сыра, перед употреблением

1) Если вам есть что сказать, скажите это прямо, а не генерите тонный бреда на аналогиях.
.
2) Кактельно учебников. Пример с животным и котом более нагляден и более «ООП», ибо он оперирует методами/сообщениями. Ваш же пример, с тяжелой коробкой — это вообще история про сишные структуры.
Как по мне то довольно хороший пример — это геометрические фигуры и их площадь. И кстати, как я заметил, он более распространен чем пример с животными.
.
Трололо секция:

Программисты на Java получают больше всего мертвых американских президентов
Не надо завидовать :)
Не надо завидовать :)

Та было бы чему.

Вам бы доктору показаться...

спасибо за комплимент, господа. возможно, я достаточно безумен чтобы строить воображаемые замки(сайты, мобильные приложения, высоконагруженные сервисы) и получать реальные деньги от людей которые потом будут жить в этих воображаемых замках :)

Подписаться на комментарии