Files
obsidian/软件需求分析/各章笔记/第04章-类图与对象图.md

17 KiB
Raw Blame History

第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. 飞机由机翼、发动机、机身组成。(飞机-机翼)
  2. 医生在医院工作。(医生-医院)
  3. 学生是人。(学生-人)
  4. 程序员写代码时用到开发工具。(程序员-开发工具)

答案:

  1. 组合关系(实心菱形)—— 机翼不能脱离飞机独立存在
  2. 关联关系(普通关联)—— 医生有"所属医院"这个属性
  3. 泛化关系(继承)—— 学生是人的子类
  4. 依赖关系(虚线箭头)—— 程序员"写代码"这个方法用到了开发工具,但不是长期持有

⚠️ 易错点:聚合和组合都表示"整体-部分",区别在于部分能否独立存在。能独立=聚合,不能独立=组合。


💡 三、关联关系的重要概念

多重性

表示法 含义
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端1Address端0..*(一个地址可以被多个员工使用)。


🔗 上一篇:第3章 用例图 | 下一篇:第5章 顺序图与协作图