Вы также можете использовать более подробный способ построения:
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
В C ++ 0x это также позволяет использовать auto
:
auto object1 = MyObject();
auto object2 = MyObject(object1);
Это может быть выполнено с помощью множественного наследования. В Вашем конкретном случае (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. Использование чистых виртуальных классов (так, чтобы они были похожи на интерфейсы) является ключевым и должно часто использоваться. Это изолирует будущие изменения от изменения всей системы. Читайте на Открыто закрытом Принципе для получения дополнительной информации.
Я думаю, что необходимо реализовывать интерфейсы, чтобы смочь осуществить Ваш, имеет отношения (делаю это в C#):
public interface IDamageable
{
void AddDamage(int i);
int DamageCount {get;}
}
Вы могли реализовать это в своих объектах:
public class Person : IDamageable
public class House : IDamageable
И Вы были бы уверены, что свойство DamageCount и имеет метод, чтобы позволить Вам добавлять повреждение, не подразумевая, что человек и дом связаны друг с другом в своего рода иерархии.
Я соглашаюсь с 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_;
};
Но многие люди не Спокойны со множественным наследованием, когда несколько родителей имеют членские переменные.
Иногда стоит бросить идеал для реалистического. Если бы это собирается заставить серьезную проблему "делать его правильно" без реальной выгоды, то я сделал бы это неправильно. После этих слов я часто думаю, что это стоит занять время, чтобы сделать его правильно, потому что ненужное множественное наследование увеличивает сложность, и это может способствовать системе, являющейся менее удобным в сопровождении. Действительно необходимо решить то, что является лучшим для обстоятельства.
Одна опция состояла бы в том, чтобы иметь эти объекты реализация a Damageable
интерфейс, вместо того, чтобы наследоваться DamageCounter
. Таким образом, человек имеет - счетчик повреждения, но является портящимся. (Я часто нахожу, что интерфейсы имеют намного больше смысла как прилагательное, чем существительные.) Затем у Вас мог быть последовательный интерфейс повреждения на Damageable
объекты, и не выставляют это, счетчик повреждения является конкретной реализацией (если Вам не нужно к).
Если Вы хотите пойти шаблонным путем (принимающий C++ или подобный), Вы могли сделать это с mixins, но это может стать ужасным действительно быстро, если сделано плохо.
Этот вопрос действительно путает:/
Ваш вопрос полужирным очень открыт и имеет ответ "его, зависит", но Ваш пример действительно не дает много информации о контексте, от которого Вы спрашиваете. Эти строки смущают меня;
наборы данных, которые должны все быть обработаны похожим способом
Какой путь? Наборы обрабатываются функцией? Другой класс? Через виртуальную функцию на данных?
В частности, различные объекты идеально действовали бы то же, которое будет очень легко достигнуто с полиморфизмом
Идеал "действия того же" и полиморфизма абсолютно не связан. Как полиморфизм помогает достигнуть?
@Kevin
Обычно то, когда мы говорим о, '' по сравнению с, 'имеет', мы говорим о Наследовании по сравнению с Составом.
Гм... счетчик повреждения просто был бы атрибутом одного из Ваших производных классов и не будет действительно обсужден с точки зрения 'Человека, счетчик повреждения' относительно Вашего вопроса.
При наличии счетчика повреждения, поскольку атрибут не позволяет ему разнообразным объектам со счетчиками повреждения в набор. Например, у человека и автомобиля могли бы оба быть счетчики повреждения, но у Вас не может быть a vector<Person|Car>
или a vector<with::getDamage()>
или что-либо подобное на большинстве языков. Если у Вас есть общий Базовый класс объектов, то можно пихнуть их таким образом, но затем Вы не можете получить доступ getDamage()
метод в общем.
Это было сущностью его вопроса, когда я считал его. "Если я нарушаю is-a
и has-a
ради обработки определенных объектов, как будто они - то же, даже при том, что они не?"
Обычно то, когда мы говорим о, '' по сравнению с, 'имеет', мы говорим о Наследовании по сравнению с Составом.
Гм... счетчик повреждения просто был бы атрибутом одного из Ваших производных классов и не будет действительно обсужден с точки зрения 'Человека, счетчик повреждения' относительно Вашего вопроса.
Посмотрите это:
http://www.artima.com/designtechniques/compoinh.html
Который мог бы помочь Вам по пути.
@Derek: От формулировки я предположил, что была основа clase, перечитав вопрос, я отчасти теперь вижу то, что он достигает.
"Делать правильно его" будет обладать преимуществами в конечном счете, если только потому, что кто-то обслуживающий систему позже найдет легче постигать, если это было сделано правильно для начала.
В зависимости от языка у Вас может быть опция множественного наследования, но обычно простые интерфейсы имеют большую часть смысла. "Простым" я имею в виду, делают интерфейс, который не пытается быть слишком много. Лучше иметь много простых интерфейсов и нескольких монолитных. Конечно, всегда существует компромисс, и слишком много интерфейсов, вероятно, привели бы к, "забываемым" о...
@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
то же при определенных очень полезных обстоятельствах.
Идея CGI заключается в том, что программа / скрипт (будь то PERL или даже C) получает входные данные через stdin (данные запроса) и выводит данные через STDOUT (ECHO, REPTFPH). Причина, по которой большинство скриптов PHP не имеют права, заключается в том, что они работают под модулем PHP Apache.
-121--1773098-Полиморфизм не требует наследства . Полиморфизм - это то, что вы получаете, когда несколько объектов реализуют одно и то же подпись сообщения (метод).