Наследование и Полиморфизм - Простота использования по сравнению с Чистотой

Вы также можете использовать более подробный способ построения:

MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);

В C ++ 0x это также позволяет использовать auto:

auto object1 = MyObject();
auto object2 = MyObject(object1);
5
задан Jason Etheridge 21 September 2008 в 07:38
поделиться

10 ответов

Это может быть выполнено с помощью множественного наследования. В Вашем конкретном случае (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;
    }
};

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

3
ответ дан 14 December 2019 в 01:22
поделиться

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

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

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

public class Person : IDamageable

public class House : IDamageable

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

5
ответ дан 14 December 2019 в 01:22
поделиться

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

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
ответ дан 14 December 2019 в 01:22
поделиться

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

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

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

0
ответ дан 14 December 2019 в 01:22
поделиться

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

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

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

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

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

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

0
ответ дан 14 December 2019 в 01:22
поделиться

@Kevin

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

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

При наличии счетчика повреждения, поскольку атрибут не позволяет ему разнообразным объектам со счетчиками повреждения в набор. Например, у человека и автомобиля могли бы оба быть счетчики повреждения, но у Вас не может быть a vector<Person|Car> или a vector<with::getDamage()> или что-либо подобное на большинстве языков. Если у Вас есть общий Базовый класс объектов, то можно пихнуть их таким образом, но затем Вы не можете получить доступ getDamage() метод в общем.

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

0
ответ дан 14 December 2019 в 01:22
поделиться

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

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

Посмотрите это:

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

Который мог бы помочь Вам по пути.

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

0
ответ дан 14 December 2019 в 01:22
поделиться

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

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

0
ответ дан 14 December 2019 в 01:22
поделиться

@Andrew

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

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

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

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

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

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

Затем можно рассматривать Person и Car то же при определенных очень полезных обстоятельствах.

0
ответ дан 14 December 2019 в 01:22
поделиться

Идея CGI заключается в том, что программа / скрипт (будь то PERL или даже C) получает входные данные через stdin (данные запроса) и выводит данные через STDOUT (ECHO, REPTFPH). Причина, по которой большинство скриптов PHP не имеют права, заключается в том, что они работают под модулем PHP Apache.

-121--1773098-

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

0
ответ дан 14 December 2019 в 01:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: