17 KiB
第4章 类图与对象图
考试重要度:★★★★★
核心内容:类与对象的识别、六大类关系、抽象类与接口、边界类/控制类/实体类
📢 从生活中理解类和对象
💬 类 = 模板,对象 = 具体的东西。
| 概念 | 生活例子 | 代码例子 |
|---|---|---|
| 类 | "汽车"这个类别 | class Car |
| 对象 | 你家楼下停的那辆红色宝马 | Car myCar = new Car() |
| 属性 | 颜色、车牌号、排量 | color, plateNumber |
| 操作 | 启动、加速、刹车 | start(), accelerate() |
例:银行的"账户"类有属性(姓名、密码、余额)和操作(查询余额、存款、取款)。张三的账户就是一个具体对象,余额是5000元。
💡 一、类的三格表示法
┌──────────────────────┐
│ 类名 │ ← 第一格:类名
├──────────────────────┤
│ -name: String │ ← 第二格:属性
│ -age: int │
│ +count: int │
├──────────────────────┤
│ +getName(): String │ ← 第三格:操作(方法)
│ +setAge(a: int) │
└──────────────────────┘
属性语法
[可见性] 属性名 [:类型] [=初始值] [{约束}]
可见性符号
| 符号 | 名称 | 含义 |
|---|---|---|
+ |
Public(公有) | 谁都能访问 |
- |
Private(私有) | 只能类内部访问 |
# |
Protected(受保护) | 类内部+子类能访问 |
✍️ 边学边练(一)
题目:银行账户类Account有属性:账号(私有)、密码(私有)、余额(私有)、利率(公有)。请用UML类图的三格表示法写出。
答案:
┌──────────────────────┐
│ Account │
├──────────────────────┤
│ -accountNo: String │
│ -password: String │
│ -balance: double │
│ +interestRate: float│
├──────────────────────┤
│ +getBalance():double│
│ +deposit(amt) │
│ +withdraw(amt) │
└──────────────────────┘
💡 二、类之间的六大关系(重中之重!必考!)
1. 关联关系(Association)—— "认识/拥有"
含义:一个类的属性类型是另一个类。这是最基础的关系。
💬 比喻:员工"属于"某个部门——Employee类中有一个Department类型的属性。
关联关系的子类型:
| 子类型 | 说明 | 生存期 | 画法 |
|---|---|---|---|
| 普通关联 | 平等关系 | 各自独立 | 实线 |
| 聚合(Aggregation) | 整体-部分,弱关系 | 部分可独立存在 | 空心菱形 |
| 组合(Composition) | 整体-部分,强关系 | 部分随整体消亡 | 实心菱形 |
💬 聚合 vs 组合:
- 聚合:学校由学生组成,学校解散了,学生还在。
- 组合:汽车由发动机组成,汽车报废了,发动机也没意义了。
2. 依赖关系(Dependency)—— "临时使用"
含义:一个类的方法的参数/返回值/局部变量用了另一个类。
💬 比喻:你去商店买东西——你跟商店的关系只在买东西那一刻存在,买完就没关系了。
3. 泛化关系(Generalization)—— "是……的一种"
含义:子类继承父类的属性和方法。
💬 比喻:狗是动物的一种——狗继承了动物的所有特征,还有自己特有的"汪汪叫"。
4. 实现关系(Realization)—— "履行接口约定"
含义:类实现了接口中定义的所有方法。
关联 vs 依赖 对比
| 维度 | 关联 | 依赖 |
|---|---|---|
| 强度 | 强,长期稳定 | 弱,临时短暂 |
| 代码体现 | 属性类型是另一个类 | 方法参数/局部变量用了另一个类 |
| 生命周期 | 对象存在就有关系 | 方法调用结束关系就结束 |
| 画法 | 实线 | 虚线箭头 |
✍️ 边学边练(二)
题目:判断以下场景属于什么关系。
- 飞机由机翼、发动机、机身组成。(飞机-机翼)
- 医生在医院工作。(医生-医院)
- 学生是人。(学生-人)
- 程序员写代码时用到开发工具。(程序员-开发工具)
答案:
- 组合关系(实心菱形)—— 机翼不能脱离飞机独立存在
- 关联关系(普通关联)—— 医生有"所属医院"这个属性
- 泛化关系(继承)—— 学生是人的子类
- 依赖关系(虚线箭头)—— 程序员"写代码"这个方法用到了开发工具,但不是长期持有
⚠️ 易错点:聚合和组合都表示"整体-部分",区别在于部分能否独立存在。能独立=聚合,不能独立=组合。
💡 三、关联关系的重要概念
多重性
| 表示法 | 含义 |
|---|---|
1 |
恰好1个 |
0..1 |
0个或1个 |
0..* 或 * |
0个或多个 |
1..* |
至少1个 |
n..m |
n到m个 |
例:一个学生选**0..*门课,一门课被1..***个学生选。
关联类
当一个属性放在哪个类都不合适时,就用关联类。
💬 例:员工和公司之间有个"合同"——合同有"工资"属性。工资既不是员工的固有属性(换公司会变),也不是公司的固有属性。所以"合同"是一个关联类。
限定关联
用限定符把多对多变成一对多,提高查询效率。
💬 例:一个人可以在多家银行开户(多对多)。但如果限定"在某家银行",就变成一对多了。
💡 四、抽象类 vs 接口
| 维度 | 抽象类 | 接口 |
|---|---|---|
| 属性 | 可以有 | 不能有 |
| 方法实现 | 部分方法有实现 | 所有方法都没有实现 |
| 关系 | 子类继承(泛化) | 类实现(实现关系) |
| 多重性 | 只能继承一个 | 可以实现多个 |
| 关键词 | abstract class |
interface |
💬 比喻:抽象类像"半成品家具"(有些部分做好了,有些需要你自己完成);接口像"插座标准"(只规定了插孔形状和电压,具体怎么发电不管)。
💡 五、版型:边界类、控制类、实体类
这是MVC模式的UML体现,期中考试经常考!
| 版型 | 职责 | 常见形式 | 对应MVC |
|---|---|---|---|
边界类 <<boundary>> |
与外界交互 | 窗口、对话框、报表 | View |
控制类 <<control>> |
协调业务逻辑 | 处理业务规则 | Controller |
实体类 <<entity>> |
持久化数据 | 数据库表对应的类 | Model |
🔑 协作关系:边界类接收用户输入 → 控制类处理业务逻辑 → 实体类存取数据。
📌 附录:类图常用画图符号速查
这一节把类图中所有的关系符号、接口、抽象类、版型、对象图等所有画图元素用字符画列出来,画类图时直接照搬即可。
1. 关联关系(Association)—— 实线(可带多重性)
普通关联(双向带多重性):
┌────────┐ 1 0..* ┌────────┐
│ 老师 │ ────────────────── │ 学生 │
└────────┘ └────────┘
自关联(一个类关联到自己):
┌────────┐
│ 员工 │
│ │
│ 领导 │◀──┐
└────────┘ │
│ │
└─────┘
2. 聚合关系(Aggregation)—— 实线 + 空心菱形 ◇
部分可脱离整体独立存在。
◇
┌────────┐ ┌────────┐
│ 班级 │ ───────────── │ 学生 │
└────────┘ └────────┘
(整体) (部分,可独立)
💬 学校没了,学生还在 —— 所以是空心菱形
3. 组合关系(Composition)—— 实线 + 实心菱形 ◆
部分不能脱离整体独立存在。
◆
┌────────┐ ┌────────┐
│ 汽车 │ ───────────── │ 发动机 │
└────────┘ └────────┘
(整体) (部分,离不开整体)
💬 汽车报废了,发动机也没意义了 —— 所以是实心菱形
4. 依赖关系(Dependency)—— 虚线 + 开放箭头
┌────────┐ ┌────────┐
│ 司机 │ ─ ─ ─ ─ ─ ─ ─⇨ │ 汽车 │
└────────┘ └────────┘
(使用者) (被使用者)
(虚线 + 开放箭头)
5. 泛化关系(Generalization)—— 实线 + 空心三角
方向:子类 → 父类(空心三角指向父类)。
▷
┌────────┐ ┌────────┐
│ 狗 │ ───────────── │ 动物 │
└────────┘ └────────┘
(子类) (父类)
6. 实现关系(Realization)—— 虚线 + 空心三角
方向:实现类 → 接口(空心三角指向接口)。
▷
┌────────┐ ┌──────────────┐
│ 鸟 │ ─ ─ ─ ─ ─ ─ ─ │<<interface>>│
└────────┘ │ 飞行 │
(实现类) └──────────────┘
(接口)
7. 接口的两种画法
普通矩形画法(在类图中更常见):
┌──────────────────┐
│ <<interface>> │ ← 关键字标识
│ 飞行 │ ← 接口名
├──────────────────┤
│ +起飞(): void │ ← 只有声明,没有实现
│ +降落(): void │
└──────────────────┘
棒棒糖表示法(简化版,常在组件图中使用):
┌────────┐ ┌────────┐
│ 鸟 │●─ ─ ─ ─ ─ ─ ─ ─ ─ ┤ 飞行 │ (棒棒糖+连接线)
└────────┘ └────────┘
(实现类) (接口)
8. 抽象类与抽象方法
画法:抽象类类名用斜体、抽象方法方法名用斜体。在字符画里用
<<abstract>>标识或加文字说明。
┌────────────┐
│ 动物 │ ← 实际画图时类名用斜体
├────────────┤
│ │
├────────────┤
│ 移动() │ ← 实际画图时方法名用斜体
│ 叫() │
└────────────┘
{abstract} ← 标注方式(实际画图用斜体)
9. 版型(Stereotype)的画法
边界类:
┌────────────────┐
│ <<boundary>> │ ← 写在类名上方
│ 登录页面 │
├────────────────┤
│ -用户名:String │
│ -密码:String │
├────────────────┤
│ +提交():void │
└────────────────┘
控制类:
┌────────────────┐
│ <<control>> │
│ 订单处理 │
├────────────────┤
│ │
├────────────────┤
│ +处理订单() │
│ +检查库存() │
└────────────────┘
实体类:
┌────────────────┐
│ <<entity>> │
│ 订单 │
├────────────────┤
│ -订单号:String│
│ -金额:double │
├────────────────┤
│ +保存() │
│ +查询() │
└────────────────┘
10. 对象图的画法
对象名格式:
对象名:类名(对象名和类名下加下划线),属性有具体值。
┌─────────────────┐
│ 张三:员工 │ ← 对象名:类名,下划线
├─────────────────┤
│ 员工号 = "E001" │ ← 属性=值
│ 姓名 = "张三" │
│ 年龄 = 28 │
└─────────────────┘
对象图与类图对比:
类图(描述规则) 对象图(描述实例)
┌──────────┐ ┌────────────────┐
│ 员工 │ │ 张三:员工 │
├──────────┤ ├────────────────┤
│ -员工号 │ │ 员工号="E001" │
│ -姓名 │ ──> │ 姓名="张三" │
│ -年龄 │ │ 年龄=28 │
├──────────┤ └────────────────┘
│ +查询() │
└──────────┘
11. 关联类的画法
关联类挂在关联线中间,用虚线连到关联线上。
┌────────┐ ┌────────┐
│ 员工 │ ─ ─ ─ ─ ─ ─ ─ │ 公司 │
└────────┘ │ └────────┘
│
┌────────┐
│ 合同 │ ← 关联类(虚线连到关联线上)
├────────┤
│ -工资 │
│ -合同期│
└────────┘
🔑 一句话记忆口诀:实线实箭是关联,空心菱形是聚合,实心菱形是组合,虚线开放箭头是依赖;实线空三角是泛化(继承),虚线空三角是实现(接口)。
✍️ 边学边练(三)
题目:在线购物系统中,"用户"通过"购物页面"下单,系统"订单处理"模块检查库存后,更新"订单"数据和"库存"数据。请指出各属于哪种版型。
答案:
- 购物页面 → 边界类(与用户交互)
- 订单处理模块 → 控制类(协调业务逻辑)
- 订单、库存 → 实体类(持久化的数据)
完整流程:边界类("购物页面") → 控制类("订单处理") → 实体类("订单""库存")
💡 六、对象图
对象图 = 类图的"截图"。类图描述通用规则,对象图描述某一时刻的具体情况。
| 类图 | 对象图 |
|---|---|
| 三个格子(类名+属性+操作) | 两个格子(对象名:类名 + 属性值) |
| 描述所有可能的情况 | 描述某一个时刻的快照 |
| 属性定义特征(如"姓名: String") | 属性有具体值(如"姓名 = 张三") |
💬 比喻:类图像"菜单"(描述菜的做法),对象图像"上桌的菜"(一份具体的菜)。
📝 章末自测
1. 填空题
- 聚合关系中,整体不存在了,部分( ___ )存在。(能/不能)
- 组合关系中,整体不存在了,部分( ___ )存在。(能/不能)
- 边界类、控制类、实体类分别对应MVC中的( _____ )、( _____ )、( ___ )
2. 判断题
- ( ) 依赖关系比关联关系更弱
- ( ) 接口可以有属性
- ( ) 抽象类可以被实例化
- ( ) 对象图是类图的实例
- ( ) 一个类只能继承一个抽象类,但可以实现多个接口
3. 分析题
- 职工类Employee包含属性empcode、name、address、birthday。Address类包含houseNumber、streetNumber、city、zipcode。分析两个类之间的关系。
答案: 填空题:能、不能、View、Controller、Model
判断题:✅ ❌(接口无属性) ❌(抽象类不能实例化) ✅ ✅
分析题:关联关系。因为Employee类中有一个属性address,其类型是Address类。这是一个长期稳定的结构关系。多重性:Employee端1,Address端0..*(一个地址可以被多个员工使用)。
🔗 上一篇:第3章 用例图 | 下一篇:第5章 顺序图与协作图