类与类之间存在六种关系
继承(Generalization)
实现(Realization)
依赖(Dependency)
关联(Association)
聚合(Aggregation Association)
组合(Composition Association)
根据语义,分为三类:
- 泛化(Generalization)
- 继承
- 实现
- 依赖(Dependency)
- 关联(Association)
- 关联(Association)
- 聚合(Aggregation Association)
- 组合(Composition Association)
语义:
关系 | 语义 |
---|---|
泛化 | is a/an |
依赖 | use a/an |
关联 | has a/an |
聚合 | has a/an |
组合 | contains a/an |
比较
依赖和关联
从语义角度看,依赖是使用(use a/an),是临时的;关联是从属(has a/an),是长期的。
从代码角度看,依赖是临时的,通常采用局部变量、方法参数的形式;关联需要长期持有,通常采用实例变量的形式。
从使用者的角度看,依赖使用局部变量、方法参数保存对象,外部无法访问所依赖的对象;关联使用实例变量保存对象,可以通过访问实例变量来访问所关联的对象。
关系 | 如何保存对象 | 导航性(Navigable) |
---|---|---|
依赖 | 局部变量、方法参数 | × |
关联 | 实例变量 | √ |
注:这里的关联包括关联、聚合和组合。
关联和聚合
关联和聚合在代码层面是一致的,只能从语义上来区分。关联的两个对象之间是平等的,如我和我的朋友;而聚合则是整体和局部的关系,如公司和公司的员工。
聚合和组合
从语义角度看,聚合是(has a/an),多个整体可以聚合同一个对象;组合是在(has a/an)的基础上,(contains a/an),多个整体不能组合同一个对象。
从生命周期看,聚合对象的生命周期与整体无关,整体消亡后聚合对象能够独立存活;组合对象的生命周期与整体一致,整体消亡时组合对象也应一起消亡。
从代码角度看,聚合对象依赖注入,在析构中不销毁;组合对象由自己创建,在析构中需要销毁。
关系 | 不同整体能否引用同一个对象 | 整体消亡后,引用对象是否消亡 | 引用对象的来源 |
---|---|---|---|
聚合 | √ | × | 依赖注入 |
组合 | × | √ | 内部创建 |