UML 类图是面向对象设计的 “施工图”,而依赖、继承、实现、关联、聚合、组合这六大关系,就是图中定义类与类互动规则的核心 “语法”。掌握它们,就能快速看懂类的协作逻辑与系统结构
UML类图的基本单元,类如下所示
+----------------+
| Animal | // 类名
+----------------+
| - name: String | // 属性(private)
| - age: int |
+----------------+
| + eat(): void | // 方法(public)
| + sleep(): void|
+----------------+
通常是一个三层矩形框,从上到下分别对应:
“-” 代表 private,“+” 代表 public,"#"表示protected
继承是面向对象编程中的一个基本概念,指的是子类继承父类的属性和方法
继承用于代码复用和建立类之间的层次关系,形成 is-a 关系
// 基类(父类)
class Animal {
public:
// 普通方法(会被继承)
void drink() {
cout < < "Animal is drinking" < < endl;
}
// 虚函数(用于多态)
virtual void sound() = 0; // 纯虚函数(抽象方法)
};
// 继承示例(派生类)
class People : public Animal { // 使用继承(is-a 关系)
public:
// 实现基类的纯虚函数(必须实现)
void sound() override {
cout < < "hello world!" < < endl;
}
};
UML 符号使用带空心三角形的实线(三角形指向父类,即 “谁是父,箭头指谁”)

实现通常指的是接口的实现,但C++本身并没有像Java那样的接口关键字,所以可能需要用抽象类来模拟接口,形成 can-do 关系
实现(通过抽象类)用于定义必须由子类实现的方法,确保多态性
在c++中,
// 实现示例(接口模式)
class Eating { // 模拟接口(没有成员变量)
public:
virtual void eat() = 0; // 纯虚函数(必须实现)
virtual ~Eating() {} // 虚析构函数
};
class People : public Animal, public Eating { // 多继承(实现多个接口)
public:
// 实现 Animal 的抽象方法
void sound() override {
cout < < "Chirp!" < < endl;
}
// 实现 Eating 的接口方法
void eat() override {
cout < < "Bird is eating" < < endl;
}
};
UML 符号使用带空心三角形的虚线(三角形指向接口,即 “谁是接口,箭头指谁”)

依赖是一种比较弱的关系,表示一个类使用另一个类,但生命周期上没有必然联系。比如,一个方法参数中使用了另一个类的对象,或者局部变量。这种情况下,当方法执行完毕,依赖的对象可能就被销毁了,抽象地说,类 A 的某个方法使用类 B 的对象,但 B 的对象并非 A 的成员变量,而是通过参数、局部变量或静态方法调用临时使用。
#include < iostream >
using namespace std;
class Food {
private:
int eggs;
};
class People {
public:
// 依赖关系:通过方法参数使用 Foodl
void eat(Food *food) {
eat.food();
}
};
UML 符号使用带箭头的虚线(箭头指向被依赖的类,即 “谁被用,箭头指谁”)

关联表示长期的结构性联系,表示更强的关系,通常表示成员变量,一个类包含另一个类的实例作为属性。关联有方向性,可以是单向或双向,但生命周期上,关联的对象通常由另一个类管理,比如作为成员变量存在,生命周期和包含它的对象一致
class People {
private:
chai *home;
Home *home
public:
work()
};
class Home {
private:
char* addr;
};
UML 符号使用带箭头的实线(单向关联箭头指向被关联方;双向关联无箭头,或用双向箭头)

整体与部分具有弱依赖关系,部分的生命周期独立于整体。部分可以属于多个整体或独立存在。典型的 "has-a" 关系
#include < iostream >
using namespace std;
class People {
private:
char *name;
chai *home;
public:
work()
};
class Company {
private:
People* people; // 关联关系:成员变量指向 People 对象
public:
Company(People* p) : People(p) {} // 通过构造函数传入 People 对象
void work() {
people- >work(); // 使用关联的 People 对象
}
};
UML 符号使用带空心菱形的实线(菱形在 “整体” 侧,箭头指向 “部分”)

整体与部分具有强依赖关系,部分的生命周期由整体管理。部分不能独立于整体存在。
整体类持有部分类的对象实例,部分在整体构造时创建,整体销毁时自动销毁)。
#include < iostream >
using namespace std;
class Heart {
public:
void beat() {
cout < < "Heart is beating" < < endl;
}
~Heart() {
cout < < "Heart destroyed" < < endl;
}
};
class People {
private:
Heart heart; // 组合关系:Heart 是 Person 的组成部分
public:
void live() {
heart.beat();
}
~People() {
cout < < "People destroyed" < < endl;
}
};
UML 符号使用带实心菱形的实线(菱形在 “整体” 侧,箭头指向 “部分”)

| 继承 | 实现 | 依赖 | 关联 | 组合 | 聚合 | |
|---|---|---|---|---|---|---|
| 关系强度 | "is-a" 关系 | "can-do" 关系 | 弱(临时使用) | 强(长期持有) | 强(部分依赖整体) | 弱(部分独立存在) |
| 生命周期 | 父类与子类生命周期通常独立 | 接口类不管理对象生命周期,由实现类负责 | 方法调用期间存在 | 对象实例化时建立,销毁时结束 | 整体管理部分生命周期 | 部分生命周期独立 |
| 代码体现 | 通过虚函数实现运行时多态 | 通过纯虚函数定义接口,实现类提供具体实现 | 方法参数、局部变量、静态方法调用 | 成员变量(对象、指针或引用) | 成员变量为对象(非指针) | 成员变量为指针或引用 |
| 对象管理 | 不管理对象生命周期 | 可能管理对象生命周期(如通过值或指针) | 整体析构时自动销毁部分 | 整体析构时不销毁部分 | ||
| 典型场景 | 生物分类(如猫继承动物) | 技能规范(如飞行接口) | 工具类使用(如 Worker 使用 Tool) | 实体间联系(如 Student 与 Teacher) | 生物器官与生物体(如心脏与人类) | 集合与元素(如班级与学生) |
| UML表示 | 空心三角形+实线 | 空心三角形+虚线 | 虚线箭头(-->) | 实线箭头(→) | 实心菱形箭头(♦→) | 空心菱形箭头(◇→) |

审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !