深入理解聚合关系:从基础概念到实际应用
立即解锁
发布时间: 2025-08-21 00:56:23 阅读量: 2 订阅数: 12 


Java编程艺术:从初学者到大师的进阶指南
# 深入理解聚合关系:从基础概念到实际应用
## 1. 聚合关系概述
聚合是两个对象之间的一种关联,形成整体/部分的关系。由其他对象组成的对象(即整体对象)被称为聚合对象,用于构建整体对象的对象则称为部分对象。聚合关系主要分为两种类型:简单聚合和复合聚合。
### 1.1 简单聚合与复合聚合的区别
聚合对象可以由一个或多个部分对象构建而成,它可以是简单聚合、复合聚合,或者两者的组合。简单聚合和复合聚合的区别在于整体对象与部分对象的链接方式,这种链接方式决定了谁来控制部分对象的生命周期(创建和销毁)。
### 1.2 简单聚合
如果聚合对象只是使用其部分对象,而对它们的创建或存在没有控制权,那么这种聚合关系就是简单聚合。部分对象可以在简单聚合对象的生命周期之外存在(即可以被创建和销毁),这意味着一个部分对象可能同时参与多个简单聚合关系。
Java的垃圾回收器最终会销毁未被引用的对象,但只要简单聚合对象保持对其部分对象的引用,部分对象就会保留在内存中。可以根据程序设计,将现有部分对象的引用传递给聚合对象的构造函数或其他方法,这种聚合也被称为引用包含。
### 1.3 复合聚合
如果聚合对象控制其部分对象的生命周期(即创建和销毁它们),那么它就是复合聚合。复合聚合对其部分对象的存在拥有完全控制权,这意味着复合聚合的部分对象直到聚合对象被创建时才会存在。
复合聚合的部分对象在聚合对象创建时被创建,通常在聚合对象的构造函数中完成。在Java中,程序员没有直接销毁对象的方法,必须依靠JVM的垃圾回收器来回收未被引用的对象。因此,在聚合对象的生命周期内,必须避免返回其部分对象的引用,以防止违反数据封装原则,这一规则的严格执行很大程度上取决于程序设计目标,这种聚合也被称为值包含。
### 1.4 快速回顾
聚合是两个对象之间形成整体/部分关系的关联,分为简单聚合和复合聚合。聚合类型由整体对象对其部分对象生命周期的控制程度决定。如果整体对象只是使用部分对象的服务而不控制其生命周期,则为简单聚合;如果整体对象创建并控制其部分对象的生命周期,则为复合聚合。
## 2. 在UML类图中表达聚合关系
UML类图可用于展示类之间的聚合关联,下面介绍如何使用UML类图表达简单聚合和复合聚合。
### 2.1 简单聚合
在UML图中,简单聚合通过连接整体类和部分类的线来表示。简单聚合的属性由空心菱形表示,该菱形位于连接整体类的线的一端。简单聚合表示聚合对象与其部分之间的“使用”关系,因为部分对象的生命周期不受聚合对象控制。
例如,有两个不同的简单聚合类Whole A和Whole B共享一个Part类的实例,这种共享情况可能需要线程同步。
### 2.2 复合聚合
复合聚合由实心菱形表示,该菱形位于聚合类的一侧。复合聚合对象控制其部分对象的创建,这意味着部分对象完全属于其包含的聚合对象。因此,复合聚合表示整体类和部分类之间的“包含”或“拥有”关系。
| 聚合类型 | UML表示 | 关系含义 |
| ---- | ---- | ---- |
| 简单聚合 | 空心菱形 | 使用关系 |
| 复合聚合 | 实心菱形 | 包含关系 |
## 3. 聚合关系示例代码
### 3.1 简单聚合示例
以下是一个简单聚合的示例,包含类A和类B。类A使用类B的服务,类A有一个属性`its_b`,它是对类B对象的引用。
```java
// Example 10.1: A.java
public class A {
private B its_b = null;
public A(B b_ref) {
its_b = b_ref;
System.out.println("A object created!");
}
public void makeContainedObjectSayHi() {
its_b.sayHi();
}
}
// Example 10.2: B.java
public class B {
public B() {
System.out.println("B object created!");
}
public void sayHi() {
System.out.println("Hi!");
}
}
// Example 10.3: TestDriver.java
public class TestDriver {
public static void main(String[] args) {
B b = new B();
A a = new A(b);
a.makeContainedObjectSayHi();
}
}
```
### 3.2 复合聚合示例
以下是一个复合聚合的示例,同样包含类A和类B。类A控制类B对象的创建。
```java
// Example 10.4: A.java
public class A {
private B its_b = null;
public A() {
its_b = new B();
System.out.println("A object created!");
}
public void makeContainedObjectSayHi() {
its_b.sayHi();
}
}
// Example 10.5: B.java
public class B {
public B() {
System.out.println("B object created!");
}
public void sayHi() {
System.out.println("Hi!");
}
}
// Example 10.6: TestDriver.java
public class TestDriver {
public static void main(String[] args) {
A a = new A();
a.makeContainedObjectSayHi();
}
}
```
## 4. 序列图
序列图是另一种UML图,用于说明应用程序中对象之间执行事件的顺序。在使用组合设计时,序列图尤为有用。
### 4.1 简单聚合的序列图
简单聚合示例程序的序列图展示了事件的执行顺序。用户通过运行`TestDriver`程序启动事件序列,`TestDriver`程序先创建类B的实例,然后创建类A的对象,并将类B对象的引用传递给类A的构造函数。最后,`TestDriver`程序向类A对象发送`makeContainedObjectSayHi()`消息,类A对象再向类B对象发送`sayHi()`消息,最终在控制台打印“Hi!”。
### 4.2 复合聚合的序列图
复合聚合版本的程序的序列图略有不同。`TestDriver`程序先创建类A的对象,类A对象再创建类B的对象,后续消息传递与
0
0
复制全文
相关推荐










