类(接口)的表示
类的表示
在 UML 类图中,一个矩形代表一个类,如图:
>矩形分为三部分:
第一部分为类名,如果用正体书写,说明这是可以实例化的普通类;如果用斜体书写,说明这是抽象类。
第二部分为该类的属性,书写格式为:
1 | 可见性 属性名 : 属性类型 |
可见性有以下几种:
可见性 | 说明 |
---|---|
+ | public |
- | private |
# | protected |
第三部分为该类的方法,书写格式为:1
可见性 方法名(参数名1 : 参数类型1, ...) : 方法返回值类型
例子
假设有这样一个 Person 类:1
2
3
4
5
6
7
8public class Person {
private String mName;
private int mAge;
public void doSomething() {
}
}
那么它的类图如下:
接口的表示
和类的表示类似,接口也是用矩形表示,并且该矩形也由三部分组成。和类不同的是,第一部分需要在接口名的上方加上 <
例子
例如有个 Vehicle 接口:1
2
3
4public interface Vehicle {
String name();
void move();
}
它的类图如下:
关系
类与类(接口)间共有六种关系,下面对每种关系进行分析:
继承关系
继承关系表示父类和子类间的关系,它的符号(空心三角形 + 实线)为:
由子类指向父类,即子类 -> 父类
假如有一个 Student 类继承于 Person 类:1
2
3
4
5
6
7
8
9
10
11
12public class Person {
protected String name;
protected int age;
public void say() {}
}
public class Student extends Person {
private String mNumber;
public void study() {}
}
用类图表示如下:
接口关系
接口关系表示类和接口之间的关系,它的符号(空心三角形 + 虚线)为:
由类指向接口,即类 -> 接口
假如有一个 Car 类实现了 Vehicle 接口:1
2
3
4
5
6
7
8
9
10
11
12public interface Vehicle {
void move();
}
public class Car implements Vehicle {
private String mName;
public void move() {
}
}
用类图表示如下:
关联关系
关联关系表示一个类内部拥有另一个类,可分为以下三种:
- 单向关联
单向关联指类 A 的内部拥有类 B,但类 B 的内部没有类 A,它的符号(实线箭头)为:
例如教室内部含有桌子:1
2
3
4
5
6public class Classroom {
private List<Desk> mDesks;
}
public class Desk {
}
用类图表示如下:
- 双向关联
双向关联指类 A 的内部拥有类 B,并且类 B 的内部拥有类 A,它的符号(实线)为:
例如老师会带多个学生,而每个学生都有带他的老师:1
2
3
4
5
6
7public class Teacher {
private List<Student> mStudents;
}
public class Student {
private Teacher mTeacher;
}
用类图表示如下:
- 自关联
自关联指类 A 的内部拥有类 A(自己),它的符号和单向关联一样,不过它指向的是自己。
例如在单链表中,每个节点内部都指向下一节点:1
2
3public class Node {
private Node mNext;
}
用类图表示如下:
聚合关系
聚合关系是单向关联的一种。在这种关系中,一般是整体对象拥有个体对象。它的符号(空心菱形 + 实线)为:
其中菱形那头连着整体对象,另一头连着个体对象。
整体对象和个体对象的生命周期不同,整体不存在了,个体依然存在。例如 Team 拥有 Person,当 Team 解散了,Person 并不会消失,它还可以加入其它的 Team。
在代码中实现聚合关系时,通常将个体对象通过构造方法的参数注入到整体对象中:1
2
3
4
5
6
7public class Team {
private List<Person> mPersonList;
public Team(List<Person> mPersonList) {
this.mPersonList = mPersonList;
}
}
用类图表示如下:
组合关系
组合关系也是单向关联的一种。和聚合关系类似,一般是整体对象拥有个体对象。它的符号(实心菱形 + 实线)为:
其中菱形那头连着整体对象,另一头连着个体对象。
和聚合关系不同的是,在组合关系中,整体对象和个体对象的生命周期一致,整体消亡时个体也会跟着消亡。例如 Person 由 Head、Body、Hand、Leg 等组成,当 Person 消亡时,其组成成分也跟着消亡。
在代码中实现组合关系时,通常在构造方法内部创建个体对象:1
2
3
4
5
6
7
8
9
10
11
12
13public class Person {
private Head mHead;
private Body mBody;
private Hand mHand;
private Leg mLeg;
public Person() {
mHead = new Head();
mBody = new Body();
mHand = new Hand();
mLeg = new Leg();
}
}
用类图表示如下:
依赖关系
在依赖关系中,存在着依赖方和被依赖方。它的符号(虚线箭头)为:
其中箭头指向被依赖方
假设类 A 和类 B 之间存在依赖关系,类 A 依赖于类 B,那么类 A 为依赖方,类 B 为被依赖方。类 B 的变化将会影响类 A,是一种 “use-a” 关系。
通常被依赖方只是以依赖方的局部变量,方法参数,静态方法调用等形式存在,而不会作为依赖方的成员。
例如 Person 依赖于 Car:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class Person {
// 局部变量
public void drive() {
Car car = new Car();
// ...
}
}
public class Person {
// 方法参数
public void drive(Car car) {
// ...
}
}
public class Person {
// 静态方法调用
public void drive() {
Car.drive();
}
}
用类图表示如下:
小结
- 继承关系和接口关系比较容易理解,A extends B 就表示 A,B 之间有继承关系,A implements B 就表示 A,B 之间有接口关系
- 关联关系和依赖关系的不同:关联关系是一种 “has-a” 关系,A 拥有 B 时,B 作为 A 的成员存在。而依赖关系是一种 “use-a” 关系,A 依赖 B 时,B 不作为 A 的成员变量,而是以 A 的局部变量、方法参数、静态方法调用等方式存在。
- 聚合关系和组合关系都可以看作是一种单向关联。它们之间的不同在于:在聚合关系中,假设 A 拥有 B,则 B 一般是作为构造方法的参数传入,A 和 B 的生命周期不同,A 消亡时 B 还会存在。而在组合关系中,假设 A 拥有 B,则 B 一般是在构造方法内部创建,A 和 B 的生命周期相同,A 消亡时 B 也会跟着消亡。