Методические указания.
В программе классы «действуют» не изолировано, а «вступают» в некоторые отношения друг с другом. Рассмотрим ряд таких отношений:
-
зависимость,
-
целое / часть, или включение, или агрегация,
-
композиция - частный случай агрегации,
-
наследование,
-
обобщение / специализация (в языке С++ - это частный случай наследования)
-
реализация
Отношение зависимость
Это один из наиболее слабых, но при этом и очень распространенный вид отношений между классами. Он предполагает, что один классов (зависимый класс) использует возможности, предоставляемые другим классом (независимым классом). Эта отношение на диаграммах классов в унифицированном языке моделирования отображается с помощью пунктирной линии, снабженной стрелкой. Эта линия имеет следующий вид -------->. Стрелка должна указывать на независимый класс. Например, такое отношение будет иметь между пользовательским классом complex и библиотечным классом istream в том случае, когда в классе complex для реализации функции – члена void complex :: input() будет использоваться библиотечный потоковый класс istream.
Для зависимости часто характерен кратковременный характер зависимости. Действительно, это имеет место в случае классов complex и istream. Зависимость проявляется только во время выполнения функции input().
Отношение целое / часть
Очень часто встречающийся вид отношения при работе на языке С++. Рассмотрим конкретный пример. Имеются два класса:
-
class room (комната),
-
class wall (стена).
Очевидно, что объект класса wall содержится в объекте класса room. Здесь объект класса room – целое, а объект класс wall – часть.
Часто это отношение справедливо называют агрегацией. На диаграммах классов UML отражают с помощью сплошной линией, которая заканчивается пустым ромбом. Ромб должен быть расположен в конце той части линии, которая находиться со стороны класса – агрегата.

Некоторые авторы — это же отношение называют включением. Рассмотрим конкретный пример. Пусть имеется класс A. Нашей задачей является разработка нового класса B, в котором предполагается воспользоваться возможностями, предоставляемыми классом B. Одним из возможных способов решить эту задачу является использование рассматриваемого вида отношения между класса. Причем возможны три варианта организации включения. Для каждого из этих вариантов для класса B выберем свое уточненное имя. В первом из вариантов в разделе реализации нового класса объявляется поле типа A (class B_1), во втором – поле типа A* (class B_2), а в третьем – поле типа A&(class B_3). Нашей задачей является рассмотрение особенностей организации конструкторов, деструктора и функции display(), выводящей на экран содержимое полей класса – агрегата.
class A
{
public:
A();
A(int n);
A(const A& rhs);
void display();
private:
int n_;
};
class B_1
{
// …
private:
A a_ ;
int m_;
};
class B_2
{
// …
private:
A* pa_;
int m_;
};
class B_3
{
private:
A& r_;
int m_;
};
Ограничимся рассмотрением организации классов B_1 и B_2, в которых используются нашедшие наиболее широкое применение варианты использования отношения включения. Реализацию класса A приводить не будем. Начнем с разработки класса B_1.
