聚合与组合都是表示整体和个体的关联关系,他们之间最大的区别在于子类被父类控制的程度。组合的父子类关系比聚合要强
聚合:has-a关系,父类包含子类,子类可以独立于父类存在
Class ==> Student
班级和学生是一种聚合关系。一个班级,可以有学生,也可以没有学生;反过来,当我们把班级解散,学生仍然存在。
public class Class {
private List<Student> students;
public Class() {} //可创建一个空班级
public Class(List<Student> students) {//可创建一个带学生的班级
this.students = students;
}
public void setStudent(List<Student> students){
this.students = students;
}
public void printAllStudent() {
for (Student student : students) {
System.out.println(student.getName());
}
}
}
组合:part-of关系,父类拥有子类,子类不能独立于父类存在
Body ⇒ Cell
身体与细胞是一个组合关系。但我们创建一个身体,细胞随之被创建;反过来,当我们销毁一个身体,细胞随之被销毁。
public class Body {
public Set<Cell> cells;
public Body() {
cells = new HashSet<Cell>();
}
public void addCells(Set<Cell> cells) {
cells.addAll(cells);
}
public void printAllCells() {
for (Cell cell : cells) {
System.out.println(cell.getCellSize());
}
}
private class Cell{//Cell作为Body内部类,与Body共存亡
private int size;
public void setCell(int size){
this.size = size;
}
}
}
不过,一个关联关系是聚合还是组合,需要根据实际的业务需求来断定。为什么这么说,因为可能相同超类和子类,在不同的业务场景,关联关系会发生变化。
就拿打车软件来说,
如果公司规定司机入驻时必须有一辆自己的车才能去载客,此时Driver和Car是组合关系,
public class Driver {
public Car car;
public Driver() {//由司机自己提供
car = new Car();
}
public void drive() {
car.start();
}
}
如果公司土豪的规定只要司机会开车,公司各种车任你挑去载客,此时Driver和Car是聚合关系
public class Driver {
public Car car;
public void setCar(Car car){//由公司提供,什么车我们不清楚
this.car = car;
}
public void drive() {
car.start();
}
}