Агрегация и композиция классов — КиберПедия 

Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Агрегация и композиция классов

2022-10-27 21
Агрегация и композиция классов 0.00 из 5.00 0 оценок
Заказать работу

 

Существует два способа повторного использования существующих классов, а именно: агрегация и наследование. При агрегации определяется новый класс, который состоит из существующих. Т.е. качестве свойств одного класса могут выступать объекты другого класса.Такойвидотношенияназывают«has-a». («Alinehastwopoints.») При наследовании новый класс создается на основе существующего с изменениями или расширениями. Такой вид отношения называют «is - a». («цилиндр – это круг с …» или «нападающий – это разновидность игрока команды»). Связи между классами на UML-диаграммах обозначаются стрелками:

Таблица 2.1 – Обозначение отношения классов на UML-диаграммах

 

Вид отношения Обозначение
агрегация
композиция
наследование

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

Рассмотрим пример. Пусть имеется класс Point, свойства которого – координаты точки на плоскости, методы – установить и получить координаты точки. Далее нам необходимо создать класс Line, который будет характеризоваться координатами начала и конца отрезка, т.е. у класса будут два свойства – точка начала и точка окончания и методы по установке значений координат точек. Диаграмма приведена на рисунке 1.3.

 

Рисунок 1.3 – Диаграмма композиции классов

 

Напишем программный код. Заголовок класса Point (сохраняется в файл.h).

class Point{

private:

float x, y; // координаты точки на плоскости       

public:

Point ();

Point (float x_, float y_);

float getX ();

void setX (float x_);

float getY ();

void setY (float y_);

void setXY(float x_, float y_);

void print ();

};

Реализация методов класса Point (сохраняется в файл. cpp).

#include "point.h"

#include <iostream>

using namespace std;

Point::Point(){

x = 0;

y = 0;

}

Point::Point (float x_, float y_){               

x = x_;

y = y_;

}

float Point::getX (){

return x;

}

voidPoint::setX (float x_){

x = x_;

}

floatPoint::getY (){

return y;

}

voidPoint::setY (float y_){

y = y_;

}

voidPoint::setXY (float x_, float y_){

x = x_;

y = y_;

}

voidPoint::print (){

cout << "(" << x << ";" << y << ")";

}

Заголовок класса-композита:

class LineComposit{

private:

Point startPoint, endPoint;

public:

LineComposit (int x1, int y1, int x2, int y2);

LineComposit (Point startPoint_, Point endPoint_);

Point getStartPoint ();

Point getEndPoint ();

void setStartPoint (Point startPoint_);

void setEndPoint (Point endPoint_);

int getStartPointX ();

void setStartPointX (int x);

int getStartPointY ();

void setStartPointY (int y);

void setStartPointXY (int x, int y);

int getEndPointX ();

void setEndPointX (int x);

int getEndPointY ();

void setEndPointY (int y);

void setEndPointXY (int x, int y);

void print ();

double getLength ();

};

Реализация методов класса-композита:

#include "point.h"

#include "LineComposit.h"

#include <cmath>

#include <iostream>

using namespace std;

LineComposit::LineComposit (int x1, int y1, int x2, int y2){

startPoint.setXY (x1, y1);  

endPoint.setXY (x2, y2);

}

LineComposit::LineComposit (Point startPoint_, Point endPoint_){

    startPoint = startPoint_;

    endPoint = endPoint_;

}

Point LineComposit::getStartPoint (){

    return startPoint;

}

Point LineComposit::getEndPoint (){

    return endPoint;

}

voidLineComposit::setStartPoint (Point startPoint_){

    startPoint = startPoint_;

}

voidLineComposit::setEndPoint (Point endPoint_){

    endPoint = endPoint_;

}

intLineComposit::getStartPointX (){

    return startPoint.getX ();

}

voidLineComposit::setStartPointX (int x){

    startPoint.setX (x);

}

intLineComposit::getStartPointY (){

    return startPoint.getY ();

}

voidLineComposit::setStartPointY (int y){

    startPoint.setY (y);

}

voidLineComposit::setStartPointXY (int x, int y){

    startPoint.setX (x);

    startPoint.setY (y);

}

intLineComposit::getEndPointX (){

    return endPoint.getX ();

}

void

LineComposit::setEndPointX (int x){

    endPoint.setX (x);

}

intLineComposit::getEndPointY (){

    return endPoint.getY ();

}

voidLineComposit::setEndPointY (int y){

    endPoint.setY (y);

}

voidLineComposit::setEndPointXY (int x, int y){

    endPoint.setX (x);

    endPoint.setY (y);

}

voidLineComposit::print (){

    cout << " Координаты:";

    startPoint.print ();

    endPoint.print ();

}

doubleLineComposit::getLength (){              

    float xDiff = startPoint.getX () - endPoint.getX ();

    float yDiff = startPoint.getY () - endPoint.getY ();

return sqrt (xDiff * xDiff + yDiff * yDiff);

}

Использованиеклассакомпозитавпрограмме:

#include <iostream>

#include "point.h"

#include "LineComposit.h"

using namespace std;

int main(){

LineComposit l1(3.0,0.0,4.0,0.0);

LineComposit l2(Point(3.0,0.0),Point(4.0,0.0));

l2.print();//вывод координат

cout<<"Длина отрезка l2 "<<l2.getLength()<<endl;//5

//Изменение координат точки

l2.setStartPointX(0);

l2.print();

cout<<"Длина отрезка l2 "<<l2.getLength()<<endl;//4

return 0;

}

Рассмотрим ситуацию агрегации. Т.е. на плаоскости имеются точки и через две из них можем провести линию.

Рисунок 1.4 – Диаграмма агрегации классов

 

Заголовок класса-агрегата:

class LineAgregate {// класс линия

private:

Point* startPoint,*endPoint;/*Указатели на начальную и конечную точки, объекты класса Point*/

public:

LineAgregate(Point* beginPoint_, Point* endPoint_);

Point* getStartPoint();

Point* getEndPoint();

void setStartPoint(Point* beginPoint_);

void setEndPoint(Point* endPoint_);

void print();

double getLength();

};

Реализации методов класса-агрегата:

#include "point.h"

#include "LineAgregate.h"

#include <cmath>

#include <iostream>

using namespace std;

LineAgregate::LineAgregate (Point * startPoint_, Point * endPoint_){

    startPoint = startPoint_;

    endPoint = endPoint_;

}

Point * LineAgregate::getStartPoint (){

    return startPoint;

}

Point * LineAgregate::getEndPoint () {

    return endPoint;

}

void LineAgregate::setStartPoint (Point * startPointPoint_) {

    startPoint = startPoint_;

}

void LineAgregate::setEndPoint (Point * endPoint_){

    endPoint = endPoint_;

}

void LineAgregate::print (){

    cout << "Координаты точки";

    if (startPoint!= NULL)

               startPoint->print ();

    else

              cout << "Начальная точка не опеределена";

    if (endPoint!= NULL)

               endPoint->print ();

    else

               cout << "Конечная точка не опеределена";

}

double LineAgregate::getLength (){                       

    if (startPoint == NULL || endPoint == NULL) {

              cout <<"Нельзя вычислить длину. Концы отрезка не определены.";

    return 0;

}

    float xDiff = startPoint->getX () - endPoint->getX ();

    float yDiff = startPoint->getY () - endPoint->getY ();

return sqrt (xDiff * xDiff + yDiff * yDiff);

}

Использование класса-агрегата в главной прогамме:

#include <iostream>

#include "point.h"

#include "LineAgregate.h"

using namespace std;

int main(){

Point p11(3, 0);//создание точки с координатами (3;0)

Point p12(0, 4);//создание точки с координатами (4;0)

LineAgregate l1 (&p11, &p12);//создание отрезка из двух точек р1 и р2

l1.print();

cout<<"Длина отрезка l1 "<<l1.getLength()<<endl;//5

p11.setX(0);

l1.print();

cout<<"Длина отрезка l1 "<<l1.getLength()<<endl;//4

l1.setStartPoint(NULL);

l1.print();

cout<<"Длина отрезка l1 "<<l1.getLength()<<endl;//4

printf("Hello World");

return 0;

}

 

Контрольные вопросы и задания

1. Что такое композиция классов? Чем она отличается от агрегации?

2. Как обозначаются отношения объектов на UML-диаграммах?

3. Как обращаться к свойствам и методам «составного» класса?

4. Произведите декомпозицию объекта шкаф-купе на составляющие его объекты.

 


Поделиться с друзьями:

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Семя – орган полового размножения и расселения растений: наружи у семян имеется плотный покров – кожура...

Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.042 с.