聚合(Aggregation)
如果一个类的实例作为另一个类的属性,则称之为聚合,这两个类之间存在has a"的关系。
在聚合中,部分与整体之间的关系比较松散,如:一个学院由许多老师组成,缺少一个老师,这个学院依然存在,老师离开了学院依旧是一个老师。这意味着聚合中的两种类(或实体)是可以单独存在的,不会相互影响。
在UML类图设计中,聚合关系以空心菱形加实线箭头表示:
class Student{
String name; // 学生姓名
int age; // 学生年龄
Family family; // Family是一个属性
}
class Student{
String name; // 学生姓名
int age; // 学生年龄
Family family; // Family是一个属性
}
从这两块代码可以看出,在Student这个类中,除了字符串类型的姓名,整型类的年龄这两个属性之外,还有Parent这个类对象。因此关系是:Student has a Parent。
在聚合中,has 不是 must has,a可以有b,也可以没有。a是整体,b是部分,整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。
ps:在一个类中使用另一个类的实例时,使用的是地址,而非开辟了一块新的空间。
## 何时使用聚合
- 当没有is-a关系时,通过聚合也能最好地实现代码重用。
- 只有在所涉及的对象的整个生命周期内维持关系为is-a时,才应使用继承; 否则,聚合是最好的选择
组合(Composition)
组合是聚合的一个受限制形式,其中的两个实例之间是高度依赖,不可分割的,如:人体离开心脏就会死亡,而人体死亡时心脏也无法起作用。在组合中,两个类之间的关系是"part-of"。
在UML类图设计中,组合关系以实心菱形加实线箭头表示:
class Person{
Message message;
Body body = new Body();
}
class Message{
String name;
int age;
}
class Body{
String eyes;
String head;
}
在上面的代码中,Person这个类中,有Message类和Body类,但是用用方式不同,引用Message这个类时,引用的是地址,而Body是开辟了一块新的空间。
在组合中,整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。
聚合与组合的关系
1. 依赖性区别
聚合中的两种类(或实体)是可以单独存在的,不会相互影响;被关联的一方可以独立于关联一方,依赖性不强。
相反,组合中的两个实体(或者类)是高度依赖于彼此的,它们之间会相互影响。
2.关联强度不同
在聚合中,部分与整体之间的关系较为松散,而组合中部分与整体的关系较为紧凑。当然,松散与紧凑是相对的。
3.生命周期不同
聚合关系中,整体不会拥有部分的生命周期,所以删除整体时,部分不会被删除。并且,多个整体可以共享同一个部分。
组合关系中,整体拥有部分的生命周期,所以整体删除时,部分一定会跟着删除。而且,多个整体不可以同时间共享同一个部分。
4.关系类型不同
聚合关系是【has-a】关系,组合关系是【part-of】关系。