UML 类图
矩形图表示类,斜体是抽象类,+表示 public,-表示 private,#表示 protected,第二层变量,第三层方法

- 继承:空三角箭头实线表示继承。B 继承 A,B 指向 A
- 实现:空三角箭头虚线表示实现
- 关联:关联用实线箭头表示,B 知道 A
- 依赖:动物的几大特征,比如有新陈代谢,能繁殖。而动物要有生命力,需要氧气、水以及食物等。也就是说,动物依赖于氧气和水。他们之间是依赖关系(Dependency),用虚线箭头来表示。
- 聚合:聚合表示一种弱的拥有关系,体现的是 A 对象可以包含 B 对象,但 B 对象不是 A 对象的一部分。聚合关系用空心的菱形 + 实线箭头来表示。
- 组合:组合(Composition)是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。组合关系用实心的菱形 + 实线箭头来表示。
继承、实现、依赖、关联、聚合、组合的联系与区别
分别介绍这几种关系:
继承
指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系;在 Java 中此类关系通过关键字 extends 明确标识,在设计时一般没有争议性;
实现
用来实现一个接口,在 Java 中使用 implements 关键字。
依赖
和关联关系不同的是,依赖关系是在运行过程中起作用的。A 类和 B 类是依赖关系主要有三种形式:
- A 类是 B 类方法的局部变量;
- A 类是 B 类方法的参数;
- A 类向 B 类发送消息,从而影响 B 类发生变化。
关联
表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。
他体现的是两个类、或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友;这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的、关联可以是单向、双向的;表现在代码层面,为被关联类 B 以类属性的形式出现在关联类 A 中,也可能是关联类 A 引用了一个类型为被关联类 B 的全局变量;
ER 图的那种关联关系
聚合
表示整体由部分组成,但是整体和部分不是强依赖的,整体不存在了部分还是会存在。
聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即 has-a 的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享;比如计算机与 CPU、公司与员工的关系等;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
组合
和聚合不同,组合中整体和部分是强依赖的,整体不存在了部分也不存在了。比如公司和部门,公司没了部门就不存在了。但是公司和员工就属于聚合关系了,因为公司没了员工还在。
但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖;
关联 vs 依赖
关联: 表示不同类对象之间有关联,这是一种静态关系,与运行过程的状态无关,在最开始就可以确定。
依赖: 和关联关系不同的是,依赖关系是在运行过程中起作用的。
A 类和 B 类是依赖关系主要有三种形式:
- A 类是 B 类方法的局部变量;
- A 类是 B 类方法的参数;
- A 类向 B 类发送消息,从而影响 B 类发生变化。
is-a,has-a,contains-a 怎样应用
is-a = 继承
has a = 聚合
contains-a = 组合
假设你确定两件对象之间是 is-a 的关系,那么此时你应该使用继承。比方菱形、圆形和方形都是形状的一种。那么他们都应该从形状类继承。
假设你确定两件对象之间是 has-a 的关系,那么此时你应该使用聚合。比方电脑是由显示器、CPU、硬盘等组成的。那么你应该把显示器、CPU、硬盘这些类聚合成电脑类。
假设你确定两件对象之间是 contains-a 的关系,那么此时你应该使用组合。比方空调继承于制冷机,但它同一时候有加热功能。那么你应该把让空调继承制冷机类,并实现接口。