You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以编程方式区分Composition(组合)与Aggregation(聚合)

如何在Java中编程区分聚合(Aggregation)和组合(Composition)

嘿,我懂你已经摸透了这俩概念的核心差异——组合里的子对象压根没法脱离父对象单独存活,聚合里的子对象完全可以自己独立存在。那咱们直接用Java代码示例把这个差异落地,一看就明白!

聚合(Aggregation)示例

聚合的核心是子对象的生命周期独立于父对象,通常是外部创建好子对象后,传递给父对象使用,子对象还能被其他对象引用。

比如部门(Department)和员工(Employee)的关系:一个员工可以属于多个部门,就算部门解散了,员工依然存在。

class Employee {
    private String name;

    public Employee(String name) {
        this.name = name;
    }

    // getter、setter省略
}

class Department {
    private List<Employee> employees;

    // 外部传入员工列表,不是内部创建
    public Department(List<Employee> employees) {
        this.employees = employees;
    }

    // 部门的业务方法
    public void showEmployees() {
        employees.forEach(emp -> System.out.println(emp.getName()));
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        // 先创建员工(独立于部门存在)
        Employee emp1 = new Employee("Alice");
        Employee emp2 = new Employee("Bob");

        List<Employee> empList = Arrays.asList(emp1, emp2);
        // 把员工传入部门
        Department devDept = new Department(empList);
        devDept.showEmployees();

        // 就算devDept被销毁(比如置为null),emp1、emp2依然存在,还能被其他部门使用
        Department hrDept = new Department(empList);
    }
}

这里的关键是:Employee实例是在Department外部创建的,Department只是持有它的引用,并没有控制它的生命周期。

组合(Composition)示例

组合的核心是子对象的生命周期完全依赖父对象,子对象由父对象内部创建,只能属于当前父对象,父对象销毁时,子对象也会被回收(因为没有其他引用指向它)。

比如汽车(Car)和引擎(Engine)的关系:引擎是汽车的一部分,没有汽车的话,这个引擎就没有存在的意义,而且一个引擎只能属于一辆汽车。

class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public void start() {
        System.out.println(type + "引擎启动");
    }
}

class Car {
    private Engine engine;

    // 汽车内部创建引擎,外部无法直接访问这个engine实例
    public Car(String engineType) {
        this.engine = new Engine(engineType);
    }

    public void startCar() {
        engine.start();
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        // 创建汽车时,自动创建内部的引擎
        Car myCar = new Car("V6");
        myCar.startCar();

        // 当myCar被置为null(销毁),内部的engine实例因为没有其他引用,会被GC回收
        myCar = null;
    }
}

这里的关键是:Engine实例是在Car的构造方法里创建的,外部没有办法获取到这个Engine的引用,它的生命周期完全绑定在Car上。

核心区分点总结

  • 聚合:子对象由外部实例化后传入父对象,父对象和子对象是"has-a"的松散关联,子对象可以被多个父对象共享,生命周期独立。
  • 组合:子对象由父对象内部实例化,是"part-of"的强依赖关系,子对象只能属于当前父对象,父对象销毁则子对象也随之消亡。

内容的提问来源于stack exchange,提问作者varmashrivastava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:58:27