【Java三种聚合方式之生命周期】
在 Java 中,**聚合(Aggregation)**关系体现的是一种较弱的包含关系。被聚合的对象的生命周期独立于容器对象,即容器对象并不管理被聚合对象的创建和销毁。下面详细分析 聚合的三种方式 中 Engine
和 Car
的生命周期区别。
1. 通过构造函数传入外部创建的对象
class Engine {
public void start() {
System.out.println("发动机启动");
}
}
class Car {
private Engine engine; // 引用外部创建的 Engine 对象
// 通过构造函数接收外部传入的 Engine 对象
public Car(Engine engine) {
this.engine = engine; // 聚合:Car 使用外部创建的 Engine
}
public void drive() {
engine.start();
System.out.println("汽车正在行驶");
}
public static void main(String[] args) {
Engine engine = new Engine(); // 外部创建 Engine 对象
Car car = new Car(engine); // 将 Engine 对象传入 Car
car.drive();
}
}
生命周期分析:
Car
的生命周期:- 当通过
new Car(engine)
创建Car
对象时,Car
的生命周期开始。Car
持有一个Engine
引用,但并不负责Engine
的创建。 Car
对象在new Car()
调用时创建,但不会控制Engine
的销毁,它只持有Engine
的引用。
- 当通过
Engine
的生命周期:Engine
对象是在外部创建的(在main
方法中),它的生命周期独立于Car
对象。Engine
的创建和销毁由外部代码控制,Car
只是通过构造函数将Engine
引用传入。Engine
的销毁时机取决于外部代码的控制,而非Car
类。
总结:
Car
仅持有Engine
的引用,但它不管理Engine
的生命周期。Engine
的生命周期由外部管理,Car
仅在需要时使用。
2. 通过 Setter 方法设置对象
class Engine {
public void start() {
System.out.println("发动机启动");
}
}
class Car {
private Engine engine; // 引用外部创建的 Engine 对象
// 通过 setter 方法将外部创建的 Engine 对象注入
public void setEngine(Engine engine) {
this.engine = engine; // 聚合:Car 使用外部创建的 Engine
}
public void drive() {
engine.start();
System.out.println("汽车正在行驶");
}
public static void main(String[] args) {
Engine engine = new Engine(); // 外部创建 Engine 对象
Car car = new Car();
car.setEngine(engine); // 使用 setter 注入 Engine
car.drive();
}
}
生命周期分析:
Car
的生命周期:Car
对象的生命周期由new Car()
控制,Car
会持有一个Engine
引用,但它的生命周期不管理Engine
对象。- 在
main
方法中,Engine
是在外部创建的,并通过setEngine()
方法传递给Car
。Car
只负责使用Engine
对象,并不会销毁Engine
。
Engine
的生命周期:Engine
对象的生命周期完全独立,由外部代码控制。在Car
创建之前,Engine
已经被创建;在Car
销毁时,Engine
并不会随之销毁。- 只有外部代码显式销毁
Engine
,Engine
的生命周期才会结束。
总结:
- 在这种方式下,
Car
仅依赖于外部创建并传递给它的Engine
对象。Car
使用Engine
,但并不管理其生命周期。Engine
的销毁由外部控制。
3. 使用集合类型的聚合
import java.util.List;
import java.util.ArrayList;
class Engine {
public void start() {
System.out.println("发动机启动");
}
}
class Car {
private List<Engine> engines = new ArrayList<>(); // 聚合:Car 可以包含多个 Engine 对象
// 通过方法添加外部创建的 Engine 对象
public void addEngine(Engine engine) {
engines.add(engine); // 聚合:Car 依赖外部创建的 Engine
}
public void drive() {
for (Engine engine : engines) {
engine.start();
}
System.out.println("汽车正在行驶");
}
public static void main(String[] args) {
Engine engine1 = new Engine(); // 外部创建 Engine 对象
Engine engine2 = new Engine();
Car car = new Car();
car.addEngine(engine1); // 将 Engine 对象添加到 Car 中
car.addEngine(engine2);
car.drive();
}
}
生命周期分析:
Car
的生命周期:Car
的生命周期由new Car()
控制,Car
内部包含一个List<Engine>
用来保存Engine
对象的引用。Car
的生命周期会在new Car()
时开始,但它并不负责Engine
的创建或销毁。Car
会在addEngine()
方法中将外部创建的Engine
对象添加到engines
集合中,但是它不会管理这些对象的生命周期。
Engine
的生命周期:Engine
对象的生命周期完全独立于Car
。Engine
是在外部创建的,可以被多个Car
对象共享。Engine
对象的销毁与Car
无关,Car
只是通过addEngine()
方法持有Engine
对象的引用,并不会影响它们的生命周期。
总结:
- 在这种方式下,
Car
仅持有对Engine
对象的引用,并通过集合(如List
)来保存多个Engine
对象。Engine
的生命周期由外部控制,而Car
不负责管理这些Engine
对象的销毁。
总结对比:
方式 | Car 的生命周期 | Engine 的生命周期 |
---|---|---|
通过构造函数传入外部创建的对象 | Car 对象的生命周期由 new Car() 控制,Car 持有 Engine 引用,但不负责 Engine 的销毁 | Engine 的生命周期独立于 Car ,由外部控制,Car 不管理 Engine 的创建和销毁。 |
通过 Setter 方法设置对象 | Car 对象的生命周期由 new Car() 控制,Car 依赖外部传入的 Engine 。 | Engine 的生命周期由外部控制,不依赖于 Car ,可以在多个容器中共享。 |
使用集合类型的聚合 | Car 持有 Engine 对象的引用,Car 的生命周期与 Engine 无关,Car 不管理 Engine 的销毁。 | Engine 对象由外部创建,可以在多个 Car 对象中共享,生命周期由外部管理。 |
结论:
在 聚合(Aggregation) 关系中,Car
并不负责 Engine
对象的生命周期。无论是通过构造函数、setter 方法,还是集合类型,Car
都只是持有 Engine
对象的引用,并利用它来执行功能。Engine
对象的生命周期独立于 Car
,由外部代码控制,可以在多个容器对象(如多个 Car
实例)之间共享。