kzen.dev
  • Вопросы
  • Метки
  • Пользователи
Оповещения
Вознаграждения
Регистрация
После регистрации, сможете получать уведомления об ответах и комментариях на Ваши вопросы.
Вход
Если у Вас уже есть аккаунт, войдите чтобы проверить новые уведомления.
Тут будут вознаграждения за добавленные вопросы, ответы и комментарий.
Дополнительно
Источник
Редактировать
Cristián Romo
Cristián Romo
Вопрос

Наследование и полиморфизм - простота использования против чистоты

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

Единственное решение, которое мне приходит в голову, - это заставить члена класса возвращать правильный тип объекта при неявном кастинге, вместо того чтобы полагаться на наследование. Может быть, лучше отказаться от идеала is a / has a в обмен на простоту программирования?

Edit: Если быть более точным, то я использую C++, поэтому использование полиморфизма позволило бы различным объектам "действовать одинаково" в том смысле, что производные классы могли бы находиться в одном списке и управляться виртуальной функцией базового класса. Использование интерфейсов (или их имитация через наследование) представляется решением, которое я готов использовать.

5 2008-08-15T01:00:47+00:00 10
Jason Etheridge
Jason Etheridge
Редактировал вопрос 21-го сентября 2008 в 7:38
Программирование
oop
polymorphism
c++
inheritance
Jon Limjap
Jon Limjap
15-го августа 2008 в 1:54
2008-08-15T01:54:52+00:00
Дополнительно
Источник
Редактировать
#8415549

Я думаю, что Вы должны осуществлять интерфейсы, чтобы быть в состоянии провести в жизнь Ваш , имеет отношения (делаю это в C#):

public interface IDamageable
{
    void AddDamage(int i);
    int DamageCount {get;}
}

Вы могли осуществить это в своих объектах:

public class Person : IDamageable

public class House : IDamageable

И you' d быть уверенным, что у собственности DamageCount и есть метод, чтобы позволить Вам добавлять повреждение, не подразумевая, что человек и дом связаны друг с другом в своего рода иерархии.

5
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Решение / Ответ
 Brian
Brian
15-го августа 2008 в 3:41
2008-08-15T03:41:05+00:00
Дополнительно
Источник
Редактировать
#8415550

Это может быть достигнуто, используя несколько наследование. В Вашем конкретном случае (C ++), Вы можете использовать чистые виртуальные классы в качестве интерфейсов. Это позволяет Вам иметь несколько наследование, не создавая проблемы объема/двусмысленности. Пример:

class Damage {
    virtual void addDamage(int d) = 0;
    virtual int getDamage() = 0;
};

class Person : public virtual Damage {
    void addDamage(int d) {
        // ...
        damage += d * 2;
    }

    int getDamage() {
        return damage;
    }
};

class Car : public virtual Damage {
    void addDamage(int d) {
        // ...
        damage += d;
    }

    int getDamage() {
        return damage;
    }
};

Теперь и Человек и Автомобиль ' a\U 0026\U 0023\39; Повреждение, значение, они осуществляют интерфейс Damage. Использование чистых виртуальных классов (так, чтобы они были похожи на интерфейсы) ключевое и должно часто использоваться. Это изолирует будущие изменения от изменения всей системы. Читайте на Открыто закрытом Принципе для получения дополнительной информации.

3
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 0124816
0124816
16-го сентября 2008 в 9:56
2008-09-16T09:56:36+00:00
Дополнительно
Источник
Редактировать
#8415551

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

class IDamageable {
  virtual DamageCounter* damage_counter() = 0;
};
class DamageCounter {
  ...
};

Каждый портящийся класс тогда должен обеспечить их собственный damage_counter () членская функция. Оборотная сторона этого - то, что это создает vtable для каждого портящегося класса. Вы можете вместо этого использовать:

class Damageable {
 public:
  DamageCounter damage_counter() { return damage_counter_; }
 private:
  DamageCounter damage_counter_;
};

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

1
0
Derek Park
Derek Park
15-го августа 2008 в 1:22
2008-08-15T01:22:11+00:00
Дополнительно
Источник
Редактировать
#8415546

@Kevin

Обычно, когда мы говорим о ' a' против ' имеет a' we' ре, говорящее о Наследовании против Состава.

Гм... прилавок повреждения просто был бы признаком одного из Ваших производных классов и wouldn' t действительно быть обсужденным с точки зрения ' человек - повреждение counter' относительно Вашего вопроса.

Наличие повреждения возражает как признак doesn' t позволяют ему разнообразным объектам с прилавками повреждения в коллекцию. Например, у человека и автомобиля могли бы оба быть прилавки повреждения, но Вы can' t имеют 'vector< Person|Car&gt'; или 'vector< с:: getDamage () &gt'; или что-либо подобное на большинстве языков. Если у Вас есть общий базовый класс Объекта, то Вы можете пихнуть их таким образом, но тогда Вас can' t получают доступ 'getDamage ()' метод в общем.

Это было сущностью его вопроса, когда я прочитал его. " Если я нарушаю, '-', и 'имеет -' ради рассмотрения определенных объектов, как будто они - то же, даже при том, что они - not' t? "

0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 Andrew
Andrew
15-го августа 2008 в 1:29
2008-08-15T01:29:00+00:00
Дополнительно
Источник
Редактировать
#8415547

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

В зависимости от языка у Вас может быть выбор нескольких наследование, но обычно простые интерфейсы имеют большую часть смысла. " simple" я имею в виду, делают интерфейс этим isn' t пытающийся быть слишком много. Лучше иметь много простых интерфейсов и нескольких монолитных. Конечно, всегда есть компромисс, и слишком много интерфейсов, вероятно, привели бы к, являющимся " forgotten" о...

0
0
Derek Park
Derek Park
15-го августа 2008 в 1:29
2008-08-15T01:29:19+00:00
Дополнительно
Источник
Редактировать
#8415548

@Andrew

идеал " действуя same" и полиморфизм абсолютно не связан. Как полиморфизм облегчает достигать?

Они все имеют, например, одна функция вместе. Let' s называют его 'addDamage ()'. Если Вы хотите сделать что-то вроде этого:

foreach (obj in mylist)
    obj.addDamage(1)

Тогда Вам нужен или динамический язык, или Вам нужны они, чтобы простираться от общего родительского класса (или интерфейс). например:

class Person : DamageCounter {}
class Car : DamageCounter {}

foreach (DamageCounter d in mylist)
    d.addDamage(1)

Затем Вы можете рассматривать 'Человека' и 'Автомобиль' то же при определенных очень полезных обстоятельствах.

0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Derek Park
Derek Park
15-го августа 2008 в 1:13
2008-08-15T01:13:01+00:00
Дополнительно
Источник
Редактировать
#8415543

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

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

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

0
0
Steven  A. Lowe
Steven A. Lowe
18-го января 2010 в 9:29
2010-01-18T21:29:48+00:00
Дополнительно
Источник
Редактировать
#8415552

Полиморфизм does не требует inheritance. Полиморфизм - то, что Вы получаете, когда несколько объектов осуществляют ту же подпись сообщения (метод).

0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
 Kev
Kev
15-го августа 2008 в 1:15
2008-08-15T01:15:32+00:00
Дополнительно
Источник
Редактировать
#8415544

Обычно, когда мы говорим о 'is a' и 'has a', мы говорим о наследовании и композиции.

Счетчик повреждений будет просто атрибутом одного из ваших производных классов и не будет обсуждаться в терминах 'A person is a damage counter' по отношению к вашему вопросу.

См. это:

http://www.artima.com/designtechniques/compoinh.html

Это может помочь вам на этом пути.

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

 Community
Community
Редактировал ответ 23-го мая 2017 в 12:13
0
0
Andrew Grant
Andrew Grant
15-го августа 2008 в 1:17
2008-08-15T01:17:13+00:00
Дополнительно
Источник
Редактировать
#8415545

Этот вопрос действительно запутан :/

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

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

Каким образом? Наборы обрабатываются функцией? Другим классом? Через виртуальную функцию на данных?

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

Идеал "одинакового поведения" и полиморфизм абсолютно не связаны. Как полиморфизм позволяет легко достичь этого?

0
0
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
Похожие сообщества 10
pro.cxx
pro.cxx
6 522 пользователей
C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. No Ads, offtop, flood 2. Полные правила тут https://t.me/ProCxx/259155 Объявления о вакансиях,эвентах - в лс @AlexFails или @MasterZiV
Открыть telegram
supapro.cxx
supapro.cxx
5 407 пользователей
Чат для тех, кто немного знает C++, простые вопросы по C++, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат-флудилка — @fludpac /прогерские вопросы – @pro_prog 🚫flood, pron, spam; ✅УВАЖАЙТЕ ДРУГ ДРУГА!
Открыть telegram
Чат конференции C++ Russia
Чат конференции C++ Russia
1 259 пользователей
Канал конференции: @cpprussia_channel Ближайшая конференция — C++ Russia 2024, анонс дат будет позднее О С++ Russia 2023: https://tinyurl.com/CPPRussia2023 YouTube-канал: https://www.youtube.com/channel/UCJ9v015sPgEi0jJXe_z Саппорт: @JUGConfSupport_bot
Открыть telegram
Хирьянов Т.Ф., Алгоритмы и структуры данных (С++)
Хирьянов Т.Ф., Алгоритмы и структуры данных (С++)
1 215 пользователей
Лекции: www.youtube.com/playlist?list=PLRDzFCPr95fL_5Xvnufpwj2uYZnZBBnsr Практика: cs.mipt.ru/cpp_algo Спонсировать: www.paypal.me/tkhirianov Онлайн компилятор https://godbolt.org
Открыть telegram
Android NDK (C++) — русскоговорящее сообщество
Android NDK (C++) — русскоговорящее сообщество
836 пользователей
Общаемся на темы, посвященным Android-разработке на C++. Обмен новостями, опытом и наработками. + Про Android: @android_ru + Про iOS: @ios_ru + Канал Android: @pandroidtoday_ru + Вакансии: @mobile_jobs Рекомендуем отключить уведомления.
Открыть telegram
C++ для самых маленьких и отчаяных
C++ для самых маленьких и отчаяных
536 пользователей
Лоу левел (по среднему IQ участников) чатик По продвижению вакансий писать @vertver Флудилка чата - @hckcxx
Открыть telegram
Добавить вопрос
Категории
Все
Технологий
Культура / Отдых
Жизнь / Искусство
Наука
Профессии
Бизнес
Пользователи
Все
Новые
Популярные
1
Andrei Kalinin
Зарегистрирован 2 недели назад
2
Koroleva Ego
Зарегистрирован 1 месяц назад
3
Star Lenon
Зарегистрирован 1 месяц назад
4
Данил Жевнеров
Зарегистрирован 1 месяц назад
5
Анна Литвиненко
Зарегистрирован 2 месяца назад
Хотите что-то узнать? Задавайте Ваш вопрос на нашем сайте
ru.kzen.dev
ID
KO
RU
© kzen.dev 2023
Источник
stackoverflow.com
под лицензией cc by-sa 3.0 с атрибуцией