前言
UML 图有很多种,一般掌握类图、用例图、时序图的使用,就能完成大部分的工作。其中,类图主要显示系统中的类、接口以及它们之间的静态结构和关系的一种静态模型。
类的 UML 展示
UML 类一般由三部分组成:
- 类名
- 类的属性
- 类的操作
一个具体类的示例:
抽象类、接口的表示法
- 抽象类:类名以及抽象方法都用斜体字表示
- 接口:在类图中的第一层顶端用构造型
<<interface>>
表示,下面是接口的名字。此外,还有一种表示方法,就是类上面的一根棒棒糖(圆圈+实线),圆圈旁为接口名称。
接口示例:
类的属性
属性表示方式:1
可见性 名称:类型[=默认值]
可见性
- public : 用
+
表示 - protected: 用
#
表示 - defult : 无符号表示
- private : 用
-
表示
类的操作/方法
操作表示方式:1
可见性 名称([参数列表])[:返回类型]
其中:
- 参数列表的表示,语法和属性的定义相似,参数个数是任意的,多个参数之间用
,
隔开 - 返回类型是一个可选项,可以是基本数据类型,也可以是用户自定义类型,还可以是空类型(void)。如果是构造方法,则无返回类型。
类之间的关系
关联关系 associtaion
用于表示一类对象与另一类对象之间有联系。在 Java 中,通常将一个类的对象作为另一个类的成员变量,比如汽车和轮胎。
在 UML 类图中,用直线连接有关联关系的对象所对应的类。
双向关联
关联关系默认不强调方向,表示对象之间互相知道。—— 两个类中,互相有对方类型的成员变量。
单向关联
如果特别强调方向,就加上箭头。比如是 A -> B,则表示 A 知道 B,但 B 不知道 A。—— A 类中有 B 类型的成员变量,而 B 中则没有 A 类型的成员变量。
自关联
类的属性对象类型为该类本身。比如。树节点的左右子节点的类型依然是树节点。
聚合关系(aggregation)
has a
的关系,表示整体与部分的关系。成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在的。部分可以属于多个整体对象,也可以为多个整体对象共享,所以,聚合关系也称为共享关系。例如,公司部门与员工的关系,汽车和发动机的关系。在 UML 中,聚合关系用空心菱形的直线表示(空心菱形在整体的一方,箭头指向部分一方)。在代码实现聚合关系时,成员对象通常作为构造方法、Setter 方法或业务方法的参数注入到整体对象中。
代码示例:1
2
3
4
5
6
7
8
9
10
11
12public class Car {
private Engine e;
// 构造注入
public Car(Engine e) {
this.e = e;
}
// 设值注入
public void setEngine(Engine e) {
this.e = e;
}
}
组合关系(composition)
contains a
的关系,它同样也表示整体与部分的关系,但是组合关系中,整体对象可以控制成员变量的生命周期(皮之不存毛将焉附)。例如人的头和嘴巴。在 UML 中,组合关系用实心菱形的直线表示(实心菱形在整体的一方,箭头指向部分一方)。在代码实现组合关系时,通常在整体类的构造方法中,直接实例化成员类。
`
java
public class Head {
private Mouth mouth;
public Head() {
// 实例化成员类
mouth = new Mouth();
}
……
}
依赖关系 dependency
依赖关系是一种使用关系,在需要表示一个事物需要使用另一个事物时使用依赖关系。在大多数情况,依赖关系体现在某个类的方法使用另一个类的对象作为参数。
在 UML 中,依赖关系使用带箭头的虚线表示,由依赖的一方指向被依赖的一方。例如,驾驶员开车,在 Driver 类的 drive() 方法中,将 Car 类型的对象 car 作为一个参数传递,以便在 drive()
方法中能够调用 Car 类的 move()
方法,且驾驶员的 drive()
方法依赖车的 move()
方法,因此类 Driver 依赖类 Car
实际系统开发阶段,依赖关系通常有 3 种方式来实现:
- 最常见的就是将一个类的对象作为另一个类中方法的参数
- 在一个类的方法中将另一个类的对象作为其局部变量
- 在一个类的方法中调用另一个类的静态方法
泛化关系 generalization
泛化关系也就是继承关系,用于描述父类和子类之间的关系,其中,父类又被称为基类或超类。如果对象 A 和对象 B 之间的 is a
关系成立,那么二者之间就存在继承关系。例如,一个年薪制员工 is a
员工,那么,年薪制员工 Salary 对象和员工 Employee 对象之间存在继承关系,Employee 是父对象,Salary 对象是子对象。
在 UML 中,泛化关系用带空心三角形的直线来表示。
在代码实现时,使用面向对象的继承机制来实现泛化关系。Java 语言中使用 extends
关键字来实现继承。例如,Student 类和 Teacher 类都是 Person 的子类。
接口与实现关系 realization
在接口中,通常没有属性,而且,所有的操作都是抽象的,只有操作的声明,没有操作的实现(Java 8 开始,接口里面可以使用 default 关键字给方法增加操作的实现)。
接口之间也可以有与类之间关系的继承关系和依赖关系,但是,接口和类之间还存在一种实现关系。
在 UML 中,类与接口之间的实现关系用空心三角形的虚线来表示。例如,定义了一个交通工具接口 Vehicle,包含一个抽象操作 move()
,在类 Ship 和 Car 中,都实现了该 move()
操作。在 Java 语言中,使用 implements
关键字。
总结
参考
- 看懂UML类图和时序图
- 知乎/30分钟学会UML类图