UML 类图与 C++ 表示

一、类的属性的表示方法

在 UML 类图中,类使用包含类名、属性(field)和方法(method)且带有分割线的矩形来表示,比如下图表示一个 Employee 类,它包含 name,age 和 email这 3 个属性,以及 modifyInfo() 方法。

 _______________________
|       Employee        |
|_______________________|
| - name  : string      |
| - age   : int         |
| - email : string      |
|_______________________|
| + modifyinfo() : void |
|_______________________|

属性/方法名称前加的加号和减号表示了这个属性或方法的 可见性,UML 类图中表示可见性的符号有三种:

  • +:表示 public
  • -:表示 private
  • #:表示 protected(friendly也归入这类)

实际上,属性的完整表示方式是这样的:

  • 可见性 名称 :类型 [ = 缺省值]

其中中括号中的内容表示是可选的。

二、类的方法的表示方式

上图中我们已经看到了方法的表示形式。实际上,方法的完整表示方式如下:

  • 可见性 名称(参数列表) [ : 返回类型]

同样,中括号中的内容是可选的。

三、类与类之间关系的表示方式

1. 依赖(Dependency)(弱弱关联)

在 uml 中,依赖 表示为 带箭头的虚线箭头指向被依赖的元素。是类与类之间的连接,表示为一个类依赖于另一个类的定义,其中一个类的变化将影响另一个类。依赖总是 单向 的,不应该存在双向依赖,这一点要特别注意。更具体的说,依赖可以理解为:一个类(A)对不在其实例作用域内的另一个类或对象(B)的任何类型的引用。大致包含以下几种情况:

  1. 局部变量
  2. 方法的参数
  3. 静态方法的调用

下面是依赖关系的 uml 示意图:

综合上图,ClassA 类的实现依赖 ClassB 类,即 ClassA 类可能要用到 ClassB类的一些方法,即,要完成 ClassA 里的所有功能,一定要有 ClassB 类的某些方法协助才行。

2. 关联(Association)(弱关联)

在 uml 中,关联 表示为 带箭头的实线。关联可以是单向的,也可以是双向的, 还有自身关联是指拥有一个自身的引用。如果是双向关联,则可以表示为双向箭头,或者没有箭头,双向关联是指双方都拥有对方的引用, 都可以调用对方的公共属性和方法。一般来说,系统设计应表现为单向关联,这样利于维护。一个关联可以附加 多重性 的修饰符,表示两个类之间的数量关系。关联可以理解为:一个类(A)持有另一个类或对象(B)。具体表现为:

下面是关联关系的 uml 示例图:

上面的关联表示,一个 Employee 持有(has)0 个或多个 TimeCard,从而可以调用其中的属性或方法,但 Employee 与 TimeCard 之间没有生命期的依赖。

3. 聚合(Aggregation)(强关联)

在 uml 中,聚合 表示为 空心的菱形箭头线聚合关系 是关联关系的一种,表示一种 关联关系。对比 关联关系,两个类是处于同一个层次的。而聚合关系,两个类处于 不同的层次,强调了一个 整体/局部 的关系。

例如一辆汽车有一个引擎,4 个轮胎。在聚合关系中,体现了一种 弱拥有 的概念。也就是说,对象 A 拥有对象 B,但 B 并不是 A 的组成部分。更具体的表现为,如果 A 由 B 聚合而成,则 A 包含 B 的全局对象,但 B 对象可以不在 A 对象创建时创建。回到前面的例子,汽车对象由轮胎对象聚合而成,但是轮胎对象的生命期并不受汽车对象的左右。当汽车对象销毁时,轮胎对象也可以单独存在!

下面是聚合关系的 uml 示意图:

从代码上看,聚合和关联没有任何区别。这里仅仅体现一种概念上的含义。在创建 ClassA 的时候,不一定需要同时创建 ClassB 的实例。 表示 ClassA 由 ClassB 聚合而成,但 ClassB 可以独立存在。

简而言之,关联关系和聚合关系都需要在类 A 中持有(has)对象 B,但不同的是:

  • 在关联关系中,类 A 和类 B 是同一 Level 的,它们之间只是有关联,但并没有包含关系,不存在说类 B 是类 A 的一部分
  • 在聚合关系中,类 A 和类 B 是不同 Level 的,具体来说,类 A 是整体,它包含局部类 B,也即类 A 由类 B 构成,但局部类 B 仍然可以独立存在

4. 组合(Composition)(更强关联)

在 uml 中,组合 表示为 实心菱形箭头线。组合也叫 合成。合成关系强调了比 聚合关系 更加强的 整体/部分 的关联,例如人和四肢。和聚合关系所不同的是,在组合关系中,虽然局部不一定随着整体的销毁而销毁,但整体要么负责保持局部的存活状态,要么负责将其销毁。也就是说,组合关系中,局部的存活期一定是小于,最多是等于整体的存活期的。

下面是组合关系的 uml 示例图:

5. 泛化(Generalization)

泛化 也就是通常所谓的 继承关系,在 uml 中表示为一个 带空心三角的实线。表示为 is-a 的关系,是对象间 耦合度最大 的一种关系,子类继承父类的所有细节,并可以在此基础上添加自己的特性。

下面是泛化关系的 uml 图:

6. 实现(Realization)

所谓 实现 就是 类对接口的定义实现,表示类是接口所有特征和行为的实现。表现为 带箭头的虚线

下面的实现的uml图:

例子

下面通过一副类图包含上述六类常用关系:

example

  1. 依赖:动物依赖氧气,水
  2. 关联:当一个类知道另一个类时,可以用关联关系。现在企鹅需要知道气候的变化,了解气候的变化规律
  3. 聚合:雁群由单只大雁聚合而成,但是单只大雁可独立存在
  4. 组合:一只鸟包含两支翅膀,但是翅膀无法单独存活,即生命期在鸟的生命期内
  5. 泛化:泛化即继承,子类继承父类属性及方法,如大雁从鸟类继承而来
  6. 实现:类对接口的实现,如大雁类实现了飞翔接口的所有方法(飞),所以大雁类实现了飞翔这个接口.

关联关系

我们从 语义 的角度除法,看一看面向对象建模 依赖、关联、聚合以及组合关系 区别

  • 依赖表达:use a
  • 关联表达:has a
  • 聚合表达:owns a
  • 组合表达:is a part of

四种联系是递进的,表示对象之间的联系越来越紧密。

代码实现形式:

  • 依赖:一般对应局部变量,方法形参,静态方法调用表达
  • 关联:一般对应成员变量,有时也用方法形参的形式
  • 聚合:一般对应成员变量,聚合关系一般使用 setter 方法给成员变量赋值
  • 组合:一般来说,为了表示组合关系,常常会使用构造方法来达到初始化的目的

参考资料

posted @ 2025-06-04 12:34  光風霽月  阅读(14)  评论(0)    收藏  举报