跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

UML 类图及六大关系详解:继承、实现、依赖、关联、聚合、组合

UML 类图的基础概念及六大核心关系。内容涵盖普通类、抽象类和接口的表示方法,以及依赖、关联、聚合、组合、泛化和实现的定义与区别。通过 Java 代码示例和 UML 图形规范,阐述了各类关系的生命周期特点、耦合程度及绘制标准,帮助开发者准确设计系统架构。

落日余晖发布于 2026/3/29更新于 2026/9/1087 浏览
UML 类图及六大关系详解:继承、实现、依赖、关联、聚合、组合

一、UML 类图概述

在软件工程中,UML 类图是描述系统静态结构的标准建模语言,而类之间的六种关系是理解系统设计意图的关键。无论是阅读现有系统源码,还是进行新功能的设计开发,准确识别类之间的关系都能显著提升代码质量和可维护性。

二、速览 UML 类图基础

类图主要包含三部分:

类名:这个类有什么属性(数据) 方法:这个类能做什么

UML 类图基础结构

在所有类图形式中,常用的三种是:普通类、抽象类和接口。它们的表示方式略有差异,但结构一致。

1. 普通类(Class)

普通类是系统中最基本的构成单元,可以直接实例化。

  • Java 代码示例
public class Student {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void study() {
        System.out.println("Studying...");
    }
}
  • UML 类图示例

普通类 UML 图

2. 抽象类(Abstract Class)

抽象类是一种不能被实例化的类,通常作为父类,被子类继承。它可以包含普通方法,也可以包含抽象方法。

  • Java 代码示例
public abstract class Person {
    protected String name;
    protected int age;

    public void speak() {
        System.out.println("Person speaking...");
    }

    public abstract void work();
}
  • UML 类图示例

抽象类 UML 图

3. 接口(Interface)

接口表示一组行为能力,是一种完全抽象的类型。接口不包含实现,只规定方法签名。从 JDK 8 开始,接口可以包含普通方法(default 方法、static 方法)。

  • Java 代码示例
public interface Movable {
    void move();
}
  • UML 类图示例

除了上图中常见的 <<interface>> 类风格画法外,UML 还允许使用更简洁的棒棒糖符号(Lollipop Notation)来表示接口:

接口棒棒糖符号

UML 类图还包括枚举(Enum)、泛型类、模板类、元类等,但使用频率远不如普通类、抽象类、接口,因此本篇只介绍最常见的三种。

4. UML 类图中的表示规范(补充)

(1) 抽象方法与抽象类的表示

抽象方法的标准表示方式是在类图中将操作的名称以斜体显示。根据 UML 2.5.1 规范第 9.6.4 节(Operations Notation):

'An abstract operation or property is denoted by writing the name of the operation or property in italics.'

规范明确指出需要将操作的名称以斜体表示。在实际应用中,整个操作签名(包括方法名、参数和返回类型)通常以斜体显示,以保持视觉一致性。

说明:抽象方法优先以斜体表示,但也可以在操作签名后添加 {abstract} 注解。

抽象类的名称同样优先以斜体显示。根据 UML 2.5.1 规范第 9.2.4.1 节(Classifier Notation):

'The name of an abstract Classifier is shown in italics, where permitted by the font in use.'

作为备选或补充,可以在类名后或下方使用文本注解 {abstract},即:

'Alternatively or in addition, an abstract Classifier may be shown using the textual annotation {abstract} after or below its name.'

说明:文献写 {abstract} 是规范允许的文本注解,实际绘图中通常用刻板印象 <<abstract>>。类名斜体和 {abstract}/<<abstract>> 都表示抽象类。

(2) 静态方法与构造方法的表示

静态方法的标准表示方式是将特征名称(包括方法名、参数和返回类型)整体下划线。根据 UML 2.5.1 规范第 9.4.4 节(Static Features Notation):

'Static features are underlined in the compartments in which they appear.'

下划线覆盖整个特征名称,而不是仅在方法名前添加下划线前缀。

作为备选,可以在操作签名后添加 {static} 关键字,即:

'An Operation may be specified as static. This is shown by writing {static} after the Operation signature.'

关于构造方法,UML 规范中没有强制要求在类图中显示构造方法。通常情况下,默认的无参数构造方法可以省略显示,因为它在大多数编程语言中是隐式存在的。只有当构造方法具有特殊参数、多个重载形式或在设计中具有重要意义时,才需要在类图中明确表示。

(3) 接口的表示方式

接口的表示必须在名称上方标注关键字 «interface»。根据 UML 2.5.1 规范第 10.4.4 节(Interface Notation):

'An Interface may be designated using the default notation for Classifier with the keyword «interface».'

仅通过斜体接口名称而不添加 «interface» 关键字不能明确表示接口,因为这无法与抽象类有效区分。

接口有两种主要的表示方式:

  • 分类器矩形表示法
    • 在名称上方标注 «interface» 关键字
    • 可以显示接口的所有操作
  • 棒棒糖(Lollipop)表示法
    • 接口表示为一个圆圈(球体),通常称为棒棒糖
    • 圆圈旁标注接口名称
    • 在棒棒糖表示法中,接口通常不列出具体操作,而是通过实线连接到实现该接口的分类器

接口名称可以选择性地以斜体显示,以强调其抽象性质,但这不是必需的,因为接口的抽象性主要通过 «interface» 关键字来标识。

(4) 可见性的表示

对于具有包可见性(default/package visibility)的特征,可以使用符号 ~ 来明确表示可见性,也可以省略可见性符号。在 UML 规范中,省略可见性符号表示该特征具有包可见性,因此对于包可见性的特征,既可以明确写出 ~,也可以不写任何可见性符号,两者含义相同。

三、六大关系详解

在 UML 类图中,类与类之间最常见的关系一共有六种。每种关系都表示不同程度的'耦合'或'依赖',从最弱到最强关系如下:

1. 依赖(Dependency)

  • 含义:A 用一下 B,比如方法参数、方法返回值、方法局部变量使用到了 B。
  • Java 代码示例
class Printer {
    void print(String content) {
        System.out.println(content);
    }
}

class Document {
    String text;
    Document(String text) {
        this.text = text;
    }
    String getText() {
        return text;
    }
}

class Logger {
    void log(String msg) {
        System.out.println("Log: " + msg);
    }
}

class Office {
    Document processDocument(Document doc, Printer printer) {
        // 方法参数依赖 Printer 和 Document
        new Logger().log("Processing document"); // 局部变量依赖 Logger
        printer.print(doc.getText());
        return new Document("Processed: " + doc.getText()); // 返回值依赖 Document
    }
}
  • UML 类图示例

图形表示:虚线 + 箭头,由依赖者指向被依赖者。

依赖关系图 依赖箭头方向

如果是双向依赖的情况,首尾连接处需画两个箭头,但是这种情况极其少见且不推荐。

2. 关联(Association)

  • 含义:A 和 B 有长期的关系,A 拥有 B 的引用(如成员变量),生命周期独立。
  • Java 代码示例
class Address {
    String city;
    Address(String city) {
        this.city = city;
    }
}

class Person {
    Address address; // Person 持有 Address
}
  • UML 类图示例

图形表示:实线 + 箭头,由关联类指向被关联类。

关联关系图 关联箭头方向

有时会存在特殊的双向关联情况:类 A 持有类 B 的引用,同时类 B 也持有类 A 的引用。

  • Java 代码示例
class Person {
    Address address; // Person 持有 Address
}

class Address {
    Person person; // Address 持有 Person
}
  • UML 类图示例

双向关联图

接下来会介绍聚合 (Aggregation) 和组合 (Composition)。需要说明的是:聚合和组合关系实际上是特殊的关联关系。

关联(Association) ← 最宽泛 ├─ 聚合(Aggregation) ← 整体 - 部分,部分可独立 └─ 组合(Composition) ← 整体 - 部分,部分不可独立

聚合和组合一定是关联关系,但是关联不一定是聚合或组合关系

3. 聚合(Aggregation)

  • 含义:A 拥有 B 的引用(如成员变量),B 可以独立存在,生命周期相互独立。
  • Java 代码示例
class Student {
    String name;
    Student(String name) {
        this.name = name;
    }
}

class School {
    List<Student> students; // 学校聚合学生

    void addStudent(Student s) {
        if (students == null) students = new ArrayList<>();
        students.add(s);
    }
}
  • UML 类图示例

图形表示:实线 + 空心菱形,由部分指向整体。

聚合关系图 聚合菱形方向

为什么这是'聚合'?

  1. Student 对象不是 School 创建的,而是外部传进来的。
  2. Student 即使不属于 School 也能单独存在(比如学生可以没有学校,也能作为对象存在)。
  3. School 只是'拥有学生列表',一种'整体 - 部分但不强绑定'的关系。

因此:学生属于学校,但学生可以独立存在 → 这是'聚合'。

4. 组合(Composition)

  • 含义:A 拥有 B 的引用(如成员变量),B 随 A 的生命周期消失,无法独立存在。
  • Java 代码示例
class Engine {
    Engine() {
        System.out.println("Engine created");
    }
}

class Car {
    private Engine engine = new Engine(); // 引擎组合在汽车中

    Car() {
        System.out.println("Car created");
    }
}
  • UML 类图示例

图形表示:实线 + 实心菱形,由部分指向整体。

组合关系图 组合菱形方向

为什么这是'组合'?

  1. Engine 是 Car 自己在内部创建的,而不是外部传进来的。
  2. Engine 的存在完全依赖 Car,脱离汽车就没有意义(比如单独的引擎对象没有用途)。
  3. Car 和 Engine 是'整体 - 部分中最紧密'的关系:汽车创建,引擎就被创建。

因此:部分(Engine)不能脱离整体(Car) → 这是'组合'。

提醒:需要注意的是,聚合和组合作为特殊的关联关系,在图形表示上分别在整体端(包含端)使用空心菱形和实心菱形来标识。至于另一端(部分端)是否需要画箭头,则取决于是否需要明确表达导航方向。 无论是聚合关系还是组合关系,从整体到部分的导航性都是关系本身固有的语义,因为整体都需要通过引用来访问部分对象。因此,在部分端画箭头可以更明确地表达这种导航关系,但由于这种导航性在聚合和组合关系的语义中都已经存在,画箭头都是可选的,可以根据需要明确导航方向时使用,不画箭头也是符合规范的。 这种处理方式在聚合关系和组合关系中是统一的,因为两种关系在导航性的语义上具有相同的特性:整体都需要通过某种引用机制来访问其组成部分,无论这种拥有关系是弱的聚合关系还是强的组合关系。

在 UML 中**依赖(Dependency)与关联/组合/聚合(Association/Composition/Aggregation)是完全不同的两类关系,判断规则也完全不一样。 依赖关系看的是'使用':只要一个类在代码里出现过另一个类型的名字(包括变量类型、参数类型、返回值、new 的右边),就表示它依赖该类型。依赖是最弱的关系,属于'用到就算'。 组合/聚合看的是'结构':它们映射的是类的内部组成关系,因此只根据成员变量的声明类型(左边)**来判断,不看 new 时实际创建的子类。因为 UML 描述的是静态设计结构,而不是运行时对象。

5. 泛化(Generalization)

  • 含义:子类继承父类。
  • Java 代码示例
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
  • UML 类图示例

图形表示:实线 + 空心三角箭头,由子类指向父类。

泛化关系图 泛化箭头方向

6. 实现(Realization)

  • 含义:类实现接口。
  • Java 代码示例
interface Runnable {}
class Task implements Runnable {}
  • UML 类图示例

图形表示:虚线 + 空心三角箭头,由实现类指向接口。

实现关系图 实现箭头方向

四、总结

在 UML 类图中,六种关系从弱到强的顺序通常为: 依赖 → 关联 → 聚合 → 组合 → 泛化(继承) → 实现

画类图时没有硬性规定必须用越强越好,整体原则是尽量按真实业务关系选择最准确的那一种:

  • 能确定整体–部分,就不要只画关联,而应画聚合或组合
  • 能确定生命周期绑定,就画组合;不能确定则画聚合
  • 无法判断是否是整体–部分时,再画普通关联
  • 仅在方法中短暂使用到对方时,使用最弱的依赖

最后需要强调:聚合与组合本质上都属于关联的更精确形式。一旦确认某关系是聚合/组合,就应该直接画它们,而不是退回画成普通关联。通过以上原则,就能让你的类图相对更加准确。

目录

  1. 一、UML 类图概述
  2. 二、速览 UML 类图基础
  3. 1. 普通类(Class)
  4. 2. 抽象类(Abstract Class)
  5. 3. 接口(Interface)
  6. 4. UML 类图中的表示规范(补充)
  7. (1) 抽象方法与抽象类的表示
  8. (2) 静态方法与构造方法的表示
  9. (3) 接口的表示方式
  10. (4) 可见性的表示
  11. 三、六大关系详解
  12. 1. 依赖(Dependency)
  13. 2. 关联(Association)
  14. 3. 聚合(Aggregation)
  15. 4. 组合(Composition)
  16. 5. 泛化(Generalization)
  17. 6. 实现(Realization)
  18. 四、总结

更多推荐文章

查看全部
  • Bing Webmaster 工具使用指南:站点验证与收录提交
  • 链表实现解析:结构体与数组两种方式
  • 电商产品 AI 绘画提示词撰写实战指南
  • 提示词工程(Prompt Engineering)基础与实践指南
  • MySQL 核心解析:索引、设计、事务与视图
  • 宇树机器人 G1 二次开发:FAST-LIO 建图配置与 RViz 可视化
  • Flutter for OpenHarmony 集成 dart_openai 接入 AI 大模型
  • 基于昇腾 NPU 的 CodeLlama 模型部署与推理实践
  • AIVideo 与 Stable Diffusion 结合:自定义视频风格
  • 单链表综合练习:删除指定节点、反转链表与查找中间节点
  • 基于 SSM 框架的肉猪屠宰管理系统设计与实现
  • Redis List 在现代 C++ 中的 redis-plus-plus 实践
  • jQuery 核心知识详解:语法、DOM 操作与插件应用
  • jmx_exporter 与 OpenTelemetry 集成:Java 应用可观测性最佳实践
  • 鸿蒙电商购物全栈项目:数据安全与合规
  • 区块链基础:Web3 底层核心的分布式信任技术
  • C++ 虚函数、多态与对象内存布局
  • 微软Copilot+企业版:为什么AI智能体才是企业数字化的终极答案
  • AIGC 工作流解构:AI 短剧生产管线从手动调用到 Agent 自动化演进
  • 我用 AI 啃完 XP.1024 更新日志,比以往省心太多

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online