LINUX.ORG.RU

Ответ на: комментарий от crutch_master

где будет реализация «Бегун»? В каждом классе из кучи алкашей?

Дефолтная — в абстрактном классе Алкаш, наверное.

как это всё будет бегать, например, на костылях?

АлкашНаКостылях будет вносить свои коррективы.

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

АлкашНаКостылях будет вносить свои коррективы.

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

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

Функция в качестве аргумента требует thatThingBase

Теперь костыль стал из кривого прямым. Остаются другие проблемы. Например нужно объекты где-то хранить, делаем вектор. Тогда для животных с разными возможностями нужны будут разные типы вектора, мы не можем просто класть всех животных в один вектор базового типа. И т.п. подобная возня вызванная тем, что у нас теперь вместо одной иерархи типов фактически несколько.

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

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

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

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

Всегда можно считать, что есть суррогатный общий корень. В Java есть Object, в С++ есть void*.

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

Всегда можно считать, что есть суррогатный общий корень. В Java есть Object

И потом начинаются пляски с getClass().getName() и динамическими кастами вместо того, чтобы программировать. В итоге получаем всё неудобство и от статики и от динамики.

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

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

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

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

Можно. Для этого контракт базового класса должен предполагать, что животное может быть калечным. На вызов алкаш.беги() оно будет возвращать «ошибка - оторваны ноги», и эта ошибка должна фигурировать в описании контракта «бегун» (так что она будет понятна коду, написанному для работы с бегунами как таковыми, а не только с алкашами).

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

no-such-file, выпились, или можешь просто хотя бы не рассуждать, честное слово, программирование не твоё, тем более используя объектно-ориентированный подход!

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

Мало того, что можем, мы именно так и делаем!

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

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

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

А если то... а если сё...

Я не обожаю размышлять об алкашах.

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

Динамика создаёт меньше проблем чем решает при соблюдении трёх условий:

  1. Ты пришешь проект один.
  2. Проект достаточно компактный и хорошо спроектирован, следовательно, ты знаешь его его вдоль и поперёк.
  3. Ты невероятно внимателен.

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

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

Хотите спорить - идите в Talks.

Форум — не место для дискуссий! %)

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

Чота ты какой-то феерично тупой.

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

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

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

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

твоя проблема решатся визитором. иди кури

struct icitizen {
  virtual void meet(icop &) = 0;
};

struct icop {
  virtual void operator() (citizen1 &) = 0;
  virtual void operator() (citizen2 &) = 0;
  virtual void operator() (citizen3 &) = 0;
};

struct citizen1 : icitizen {void meet(icop &c) override {c(*this);}};
struct citizen2 : icitizen {void meet(icop &c) override {c(*this);}};
struct citizen3 : icitizen {void meet(icop &c) override {c(*this);}};


int v() {
  std::vector <icitizen *> russians = all_russians();
  struct russiancop : icop {
    void operator() (citizen1 &c) override {jail.push_back(c);}
    void operator() (citizen2 &c) override {jail.push_back(c);}
    void operator() (citizen3 &c) override {jail.push_back(c);}
  } xrussiancop;
  for (auto &some_russian : russians) {
    some_russian.meet(xrussiancop);
  }
  puts("voi la!");
}

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

писать нетипизированное говно

Нужно просто не нарушать LSP. Тогда всё гладко и шелковисто.

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

Нафига вы тут столько всего написали? Я это читать точно не буду.

Дык это не для тебя написано.

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

Человек найдет поиском эту тему и запутается окончательно.

И почему это должно быть нашей проблемой?

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

визитор
костыль

мда, тяжело быть тобой наверное

anonymous
()

Воу, на лоре разразился срачь из-за принципов SOLID. Давайте ещё про столпы ООП поспорим )))

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

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

Если у тебя есть метод Sort в базовом классе, то и наследники должны при вызове этого метода делать сортировку, а не, например, rm -rf /

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

beaver
()

Прошу извинить за тупой вопрос. Принцип LST это по сути: «пересечение множеств должно оставаться пересечением множеств»?

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

Или даже так: «подмножество должно оставаться подмножеством»?

Нет, LSP про то, что подмножество мёда должно оставаться мёдом, а подмножество говна - говном.

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

А чего тогда сразу «нет», если сам говоришь «да»?

В ООП можно сделать, чтобы мёд выглядел и пах, как мёд, а на вкус был говном. LSP же говорит о том, что так делать не стоит.

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

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

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

Ты нашел у кого спрашивать это ж бомж пхпэшник который себе на таблетки то заработать не может. Чё он там знать то может лул.

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

подмножество должно оставаться подмножеством

Кстати, если считать тип множеством, то не всегда отношение a является подтипом b означает, что A является подмножеством B, где a и b типы, а A и B - соответствующие им множества. Например, в случае с активно обсуждаемыми млекопитающими «человек является подтипом обезьяны» действительно означает, что множество людей - это подмножество обезьян. В случае же с числами целые числа являются подтипом натуральных, однако множество целых чисел, очевидно, является надмножеством натуральных.

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

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

сложна

Да, поэтому ждём, когда ботаники доведут это всё до юзабельного состояния.

не всегда работает

Сама логика работает всегда, а вот доказать, что написанный код действительно работает, получается не всегда. Поэтому, например, в реализации красно-чёрных деревьев на idris до сих пор нет операции удаления.

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

Классика с квадратом и прямоугольником рулит.

+1.

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

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

Но в динамике есть типы. Куда бы они делись?

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

Да, там можно всё выстроить с чётким и однозначным описанием и обмазываться валидаторами с ног до головы. Что мешает сделать так:

var myClass = {
  parents : [myParentClass],
  methods : {
    test : {
      arguments : {
        x : "int/notNull", y : "int", z : "string"
      },
      return : "int/notNull",
      annotations : {
        testMethod : {args : "values"}
      },
      func : function(x, y, z) {
        //...
      }
    }
  }
}
?
Проблемы динамики в том, что всё происходит в рантайме и пока не запустишь код ничего не ясно. Но в яву, например, притащили ту же динамику со спрингом, аннотациями и декларативщиной в xml. И какой профит от того, что у тебя стоят типы? Всё равно все вокруг кастят Object, дёргают за рефлексию и передавая что-то, например jackson'у на сериализацию компилятор не знает заранее чем всё это закончится.

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

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

С чего это вдруг? Наоборот, натуральное число является целым. И давайте сюда не будем вносить бесконечность, если что.

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

Специалисты утверждают что только один тип.

Интересные какие специалисты.

Значения же обычно имеют типы, а имена (символы, идентификаторы) нет? Все как в реальном мире.

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

С чего это вдруг? Наоборот, натуральное число является целым.

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

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

Что значит все «свойства натуральных чисел»?

Это про то, что арифметика Пеано не в состоянии доказать свою собственную непротиворечивость?

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

Что значит все «свойства натуральных чисел»?

Я имел в виду, что любая теорема с натуральными числами и переменными останется теоремой после их замены на целые числа. Например, в теореме ∀ a b c : ℕ -> (a + b) + c = a + (b + c) замена на оставит её теоремой.

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

множество целых чисел, очевидно, является надмножеством натуральных

Это утверждение неверно. Мощности множеств Z и N равны - счетные множества. Множество Z содержит подмножество изоморфное N. Надеюсь ты различаешь понятия «равный» и «изоморфный».

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

обязан иметь такой же интерфейс

Вообще там немного про другое, но рядом.

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

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

Дополню.

Грубо, разница между N и Z в том, что для Z аксиоматически вводится операция «+» c обратными элементами. А натуральные числа можно определить без всяких «выдуманных» операций.

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

Я имел в виду, что любая теорема с натуральными числами и переменными останется теоремой после их замены на целые числа. Например, в теореме ∀ a b c : ℕ -> (a + b) + c = a + (b + c) замена ℕ на ℤ оставит её теоремой.

Так ты тут меняешь сигнатуры (типы аргументов) теоремы, а не подставляешь значения субтипа.

Напиши простую функцию нахождения разности:

∀ x ∈ ℕ, y ∈ ℕ
x - y
    | x == 0     =  undefined
    | y == 0     =  x
    | otherwise  =  (dec x) - (dec y)

Подставь туда два отрицательных целых и посмотри, что будет.

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