Как показать агрегацию с точки зрения программного кода?
-
13-09-2019 - |
Вопрос
Я знаю об ассоциации, агрегации, композиции и обобщении, что они собой представляют по определению.наследование — это отношение «есть», а композиция — это отношение «имеет» отношение.
Class A {
}
Class B extends A { // this is Generalization
}
Class C {
A ob; // this is composition
}
теперь мой вопрос заключается в том, как агрегация и простая ассоциация отображаются с точки зрения программного кода.?
Решение
Я подозреваю, что ваш настоящий вопрос связан с композицией и агрегацией.Вы можете думать о разнице с точки зрения владения, но настоящее различие (на мой взгляд) заключается в том, что контролирует жизненный цикл агрегированного объекта.
По составу.когда составной объект уничтожается, содержащиеся в нем части или классы уничтожаются вместе с ним.При агрегировании время жизни содержащегося объекта может быть независимым от содержащего его объекта.В коде.это сводится к тому, указан ли объект компонента по значению или ссылке.Агрегация имеет это нужно сделать по ссылке (или указателю, как в примере).Если это делается по значению, часть компонента выйдет за пределы области действия и будет уничтожена вместе с содержащим объектом и, таким образом, является композицией.
Итак, в данном случае Engine — это пример композиции, а Battery — пример агрегации.
#include <iostream>
using namespace std;
class Engine
{
public:
Engine() {cout << "Engine created\n";};
~Engine() {cout << "Engine destroyed\n";};
};
class Battery
{
public:
Battery() {cout << "Battery created\n\n";};
~Battery() {cout << "\nBattery destroyed\n";};
};
class Car
{
private:
Battery *bat;
Engine eng; //Engine will go out of scope with Car
public:
Car(Battery* b) : bat(b) {cout << "Car created\n";};
~Car() {cout << "Car destroyed\n";};
void drive(int miles) {/*...*/};
};
int main(int argc, char *argv[])
{
//a Battery lifecycle exists independently of a car
Battery* battery = new Battery();
//but a car needs to aggregate a Battery to run
Car* car1 = new Car(battery);
car1->drive(5);
//car1 and its Engine destroyed but not the Battery
delete car1;
cout << "---------------\n";
//new car, new composed Engine, same old Battery
Car* car2 = new Car(battery);
car2->drive(5);
delete car2;
//destroy battery independently of the cars
delete battery;
}
Извините, если это не лучший пример, но, надеюсь, он иллюстрирует основную мысль.
Другие советы
Я не уверен, что именно вы здесь делаете, но я бы предложил следующие примеры:
Агрегация
public class A { }
public class List<A> { } // aggregation of A
Ассоциация (использование)
public class A
{
public void AMethod() { ... }
public class B
{
public void BMethod( A a )
{
a.AMethod(); // B uses A
}
}