UML类图关系(泛化 、继承、实现、依赖、关联、聚合、组合)
1. 继承
继承是指一个类(称为子类、子接口)继承令一个类(称为父类、付接口)的功能
- 子类具有可以增加它自己的新功能的能力
- 在Java中此类关系通过关键字extends明确标志
- 且子类只能继承一个父类,单继承
- 包括类继承和接口继承两种,如下图,左侧是类继承,右侧是接口继承
2. 实现
实现是指一个class类实现了interface接口
- 实现的接口可以是多个
- 在 Java 中此类关系通过implements 关键字标志
- 接口可以从行为方面考虑,多个类具有相同的行为
3. 依赖
依赖简单理解,就是一个类 A 使用到了另一个类 B
- 此种依赖关系具有偶然性额、临时性的、非常弱的
- 但是 B 类的变化会影响到 A
- 代码层的表现是,类 B 作为方法参数被 A 的某个方法使用
4. 关联
关联是两个类、或者类与接口之间语义级别的一种强依赖关系
- 这种关系比依赖更强
- 这种关系不是偶然性、也不是临时的,一般是长期、平等的
- 代码层面表现为,类B 作为属性形式出现在类A中
- 成员变量
- 类变量
5. 聚合
聚合是关联关系的一种特例
- 它体现的是整体与部分、has-a的关系
- 整体和部分之间是可分离的,而且具有各自的生命周期
- 部分可以属于多个整体对象,即部分可以“拆卸”存在其他整体对象中,也可为多个整体对象共享
- 如计算机和CPU,公司和员工
- 代码层面表现为,类B 作为属性形式出现在类A中
- 成员变量
- 类变量
6. 组合
组合也是关联关系的一种特例
- 它体现的是contains-a的关系
- 此种关系比聚合更强,也称为强聚合
- 体现整体和部分间的关系,但整体和部分不可分,整体声明周期决定着部分的生命周期
- 比如人体和到脑
-
- 代码层面表现为,类B 作为属性形式出现在类A中
- 成员变量
- 类变量
- 代码层面表现为,类B 作为属性形式出现在类A中
关系依赖强弱排序
组合>聚合>关联>依赖
组合和聚合的区别
- 3种对象:雁群(GooseGroup)-大雁(Goose)-翅膀(Wings)
- 聚合:雁群-大雁 (has-a, 生命周期独立)
- 组合:大雁-翅膀 (contain-a, 生命周期不独立)
代码层面上组合和聚合的对比
信息的封装性不同
GooseGroup 和 Goose
public class GooseGroup {
private Goose goose;
public GooseGroup(Goose goose) {
//GooseGroup 和 Goose有独立的生命周期,Goose 可对外暴露-聚合
//客户端可以同时了解 GooseGroup 和 Goose
this.goose = goose;
}
}
Goose 和 Wings
public class Goose {
private Wings wings;
public Goose() {
//Goose 负责Wings 的生命周期-组合
//客户端只认识Goose类,根本不知道Wings的存在,Winds 完全被封装到Goose中
wings = new Wings();
}
}