继承和聚合的区别在哪?¶
一、定义¶
继承(Inheritance)¶
is-a:子类是父类的一种。
Dog 是一种 Animal。
聚合(Aggregation)¶
has-a:一个类包含另一个类的引用。
Car 包含 Engine,但 Engine 可以独立存在。
二、对比¶
| 维度 | 继承 | 聚合/组合 |
|---|---|---|
| 关系 | is-a | has-a |
| 代码复用 | 白盒(子类能看到父类内部) | 黑盒(只通过接口) |
| 耦合 | 强,父类变影响子类 | 弱,通过接口交互 |
| 灵活性 | 单继承,不能多级扩展 | 可组合多个对象 |
三、为什么优先用组合/聚合¶
1. 破坏封装¶
继承中子类依赖父类实现细节,父类一改子类可能崩。
2. 编译期静态选择¶
继承是静态的,运行时不能改父类。组合可以动态换组件。
3. 单继承限制¶
Java 类只能继承一个父类,但可以组合多个对象。
四、原则¶
Favor composition over inheritance.(Effective Java 第 18 条)
- 需要
is-a且不打算扩展其他类型 → 继承。 - 需要代码复用但不是
is-a→ 组合。
五、例子¶
// 继承:Dog is an Animal
class Dog extends Animal {}
// 组合:ArrayList 包含一个 Object[]
class ArrayList<E> {
transient Object[] elementData;
}
面试加分
- 组合/聚合的区别:聚合是"弱拥有"(生命周期不绑定),组合是"强拥有"(同生共死)。
- 例如:班级和学生是聚合,订单和订单行是组合。