UML类关系理解

发现UML图还是很重要的,对于理解类与类之间的关系起着举重若轻的作用。因此今天来详细理解一下。。(文章都不知道怎么分类,瞎几把分类。。。。)

 


类之间的关系:泛化(Generalization)、依赖(Dependency)、关联(Association)、聚合(Aggregation)、组合(Composition)。

 

一、泛化

泛化表现为继承或实现关系。具体形式为类与类之间的继承关系,接口与接口之间的继承关系,类与接口的实现关系

比如在上图中,接口B继承了接口A,DerivedClass类继承了BaseClass类,即DerivedClass是子类,BaseClass是父类,ClassC类实现了接口C。

【箭头指向】:带三角箭头的实线,箭头指向父类

【箭头指向】:带三角箭头的虚线,箭头指向接口

二、关联

关联表现为变量。类与类之间的联接,它使一个类知道另一个类的属性和方法。例如如果A依赖于B,则B体现为A的全局变量。

关联关系有双向关联和单项关联。双向关联,两个类都知道另一个类的公共属性和操作。单项关联:只有一个类知道另外一个类的公共属性和操作。大多数关联应该是单向的,单向关系更容易建立和维护,有助于寻找可复用的类。

比如在上图中,老师与学生是双向关联,老师有多名学生,学生也可能有多名老师。但学生与某课程间的关系为单向关联,一名学生可能要上多门课程,课程是个抽象的东西他不拥有学生。

【代码体现】:成员变量

【箭头及指向】:带普通箭头的实心线,指向被拥有者

三、聚合

聚合是关联关系的一种,是强的关联关系。聚合关系是整体和个体的关系。普通关联关系的两个类处于同一层次上,而聚合关系的两个类处于不同的层次,一个是整体,一个是部分。同时,是一种弱的“拥有”关系。

体现为,A对象可以包含B对象,但B对象不是A对象的组成部分。

具体表现为,如果A由B聚合而成,A包含有B的全局对象,但是B对象可以不在A创建的时刻创建

【代码体现】:成员变量

【箭头及指向】:带空心菱形的实心线,菱形指向整体

四、组合

组合关系是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象 负责 代表部分的对象的生命周期。

组合关系是一种强“拥有”关系,体现了严格的部分和整体的关系,部分和整体的生命周期一致。

如果A由B组成,表现为A包含有B的全局对象,并且B对象在A创建的时刻创建。

【代码体现】:成员变量

【箭头及指向】:带实心菱形的实线,菱形指向整体

五、依赖

依赖关系表现为函数中的参数。是类与类之间的连接,表示一个类依赖于另一个类的定义,其中一个类的变化将影响另外一个类。

例如如果A依赖于B,则B体现为局部变量,方法的参数、或静态方法的调用。

【代码表现】:局部变量、方法的参数或者对静态方法的调用

【箭头及指向】:带箭头的虚线,指向被使用者

 

各种关系的强弱顺序:

泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

 


下面来个实战体验,我要把自己的理解记下来嘻嘻嘻嘻嘻嘻

实战一 (该图和以上的图都来自参考博客):

理解:

动物是父类,鸟是动物的子类,鸭子是鸟的子类,唐老鸭是鸭子的子类。         泛化之继承关系

动物依赖于氧气和水,氧气和水作为动物类方法的参数存在。                           依赖关系

鸟和翅膀是组合关系,鸟类控制翅膀类的生命周期。                                         组合关系

企鹅和气候是单向关联。                                                                                    关联关系

大雁实现飞翔,唐老鸭实现讲话                                                                          泛化之实现关系

大雁和雁群是聚合关系,雁群由多个大雁组成                                                     聚合关系

 

---------------------------好了只想了解概念的人可以撤了。下面都是我的个人秀,全程碎碎念。-----------------

 

实战二(该图来自于https://doc.cgal.org/latest/GraphicsView/index.html#title5):

理解:

QObject是父类,QGraphicsScene是其子类,QGraphicsView是其子类,CGAL::QT::GraphicsViewInput是其子类,MainWindow是其子类,CGAL::QT::GraphicsItem是其子类,同时也是QGraphicsItem的子类。

CGAL::QT::GraphicsItem和CGAL::QT::GraphicsViewInput作为抽象类,分别被CGAL::QT::TriangulationGraphicsItem<T>模板类和CGAL::QT::GraphicsViewPolylineInput<K>模板类继承。

QGraphicsScene类由QGraphicsItem类和QGraphicsView类组合而成,这两个类不能离开QGraphicsScene单独存在。

CGAL::QT::TriangulationGraphicsItem<T>模板类由CGAL::Delaunay_triangulation_2<K>模板类组合

MainWindow类由CGAL::Delaunay_triangulation_2<K>组合

CGAL::QT::GraphicsViewNavigation类和CGAL::QT::GraphicsViewPolylineInput<K>依赖QGraphicsView,通过installEventHandler()方法

MainWindow类依赖CGAL::QT::TriangulationGraphicsItem<T>模板类,通过connect()方法

恩?说的是个毛线?????????????????????????咳咳,老大请再给我一次重新组织语言的机会!!!!下面根据英文解说再来说一遍。


QGraphicsItem存储在QGraphicsScene中,并显示在QGraphicsView中项目具有一个paint方法,当项目位于视图的可见区域时,将调用该方法。框架还负责通过场景将事件从视图发送到项。该框架是可扩展的,因为用户可以添加从QGraphicsItem派生的类

除了可视化QGraphicsItems,用户还希望输入几何对象。我们为所有2D CGAL内核对象提供了输入生成器。该包还包含一个类,用于提供缩放、平移和滚动到图形视图。接下来我们描述各个类之间的交互,最后描述QGraphicsItem类的内部结构。

题外话---------说一下它们的命名规则:

由于Qt和CGAL有不同的命名约定,并且由于这个Package将它们组合在一起,我们采用了以下混合命名约定。

所有头文件都在目录CGAL/Qt/中。

类名连接大写单词,函数名连接大写单词和第一个小写单词。其基本原理是,这些类与Qt相关,并且它们有时是派生类,必须覆盖遵循此命名方案的成员函数。

所有类都位于嵌套的名称空间CGAL::Qt中。

上图这四个灰色的类来自QT图形视图框架QGraphicsScene包含QGraphicsItem,QGraphicsItem在QGraphicsView中显示,views就是widgets,占用屏幕

QObject较为基础的类,它在Qt中对事件处理和内存管理起着重要的作用。首先,它允许添加信号和插槽,并连接它们。其次,它允许事件过滤器。

上图黄色的类是CGAL用QT框架的类,红色的类是CGAL的数据结构类

绿色的类是qt中的application类。

 

 


来个例子详细点讲解,比如:

上图,为了可视化CGAL::Delaunay_triangulation_2,我们提供了图形象类CGAL::Qt::TriangulationGraphicsItem<T>,它提供了绘制方法。它使用void draw(QPainter...)绘制三角形的边和顶点,而顶点和边的颜色等属性可以通过设置QPen来选择。

由于该graphics item之存储指向三角形的指针,因此它必须通知更改---比如说来自文件的点插入,来自程序的变量更改,或者来自鼠标的输入更改。因此,我们使用Qt的信号/插槽机制。当三角形发生变化时候,应用程序发出一个信号,这个信号可以连接到图形项的modelChanged()插槽。

上图,我们提供了一个类CGAL::Qt::GraphicsViewNavigation,它可以被安装为图形视图及视图端口的事件过滤器。对于所有的Qt widgets,QGraphicsView都是从QObject派生出来的。像按下或者释放鼠标、鼠标移动、按键等事件被传递给视图,视图首先将这些事件传递给时间过滤器。

CGAL::Qt::GraphicsViewNavigation事件过滤器允许缩放、滚动、recenter,该类使用鼠标坐标发出信号。这可以用于在应用程序的状态栏中显示当前鼠标位置。

CGAL内核对象、折线等的输入由CGAL::Qt::GraphicsViewInput的派生类生成。作为导航类,它们是图形视图的事件句柄,它们必须知道鼠标在哪里,用户何时单击鼠标。

一旦输入生成器组装好对象(比如说单击鼠标),它就会发出一个CGAL::Object包住输入。发出的输入可以由程序员connect到slot。在CGAL的2D Demo里,我们使用图形视图框架将其连接到槽MainWindow::processInput(CGAL::Object)中。这个方法将CGAL::Oject展开并插入数据结构。然后,它通常发出一个信号modelChanged(),该信号可以连接到表述数据结构的图形项。

 

-----------------------------------------------------END---------------------------------------------------------------------------

参考博客:

https://blog.youkuaiyun.com/MaybeHelios/article/details/2038685

https://blog.youkuaiyun.com/qq_39627843/article/details/82560798

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

keneyr

老爷~给小的赏点盘缠吧555~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值