跳转至

继承和聚合的区别在哪?

一、定义

继承(Inheritance)

is-a:子类是父类的一种。

class Dog extends Animal {}

Dog 是一种 Animal。

聚合(Aggregation)

has-a:一个类包含另一个类的引用。

class Car {
    private Engine engine;   // Car 有一个 Engine
}

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;
}

面试加分

  • 组合/聚合的区别:聚合是"弱拥有"(生命周期不绑定),组合是"强拥有"(同生共死)。
  • 例如:班级和学生是聚合,订单和订单行是组合。