对应UML类图:
- 类名:粗体,如果是类是抽象类则类名显示为斜体!
- 属性:
可见性 名称:类型[=默认值]
可见性一般为public、private和protected,在类图分别用+、-和#表示,在Swift中没有与protected完全对应的可见控制,因此选用的是internal对应为#;名称为属性的名称;类型为数据类型;默认值如变量 age默认值为0。
- 方法:
可见性 名称(参数列表 参数1,参数2) :返回类型
可见性如上名称表达式的介绍,名称就是方法名,参数列表是可选的项,多参数的话参数直接用英文逗号隔开;返回值也是个可选项,返回值类型可以说基本的数据类型、用户自定义类型和void。如果是构造方法,则无返回类型!
类图中类与类之间的关系主要由:继承、实现、依赖、关联、聚合、组合这六大类型。表示方式如下图:
依赖
- 依赖表示一个类依赖于另一个类,即一个类通过某种方式使用到另一个类。这种关系是临时的或弱依赖的。
- 依赖关系通常意味着“使用关系”,类 A 使用了类 B 的某些功能。
A → B(A 依赖于 B),实现方式:函数参数、局部变量、静态函数调用等
class B {};
class A {
public:
void use(B& b) {
// A 使用了 B
}
}; 关联
- 关联表示两个类之间有某种关系,通常是一个类“拥有”另一个类的对象。
- 可以是单向或双向关联。
用 实线箭头 表示,箭头指向被关联的一方,双向关联时没有箭头。实现方式:成员变量表示长期持有关系。
class B {};
class A {
private:
B* b; // A 和 B 关联
}; 聚合
- 聚合是一种特殊的关联关系,表示整体和部分的关系,但部分可以独立于整体存在。
- “has-a” 的关系,整体和部分生命周期不同。
用 空心菱形 + 实线箭头 表示,菱形指向整体,箭头指向部分。实现方式:一个类通过指针或引用持有另一个类的对象。
class Engine {};
class Car {
private:
Engine* engine; // Car 聚合了 Engine
}; 组合
- 组合是一种强聚合关系,表示整体和部分不可分割,部分不能独立存在。
- “contains-a” 的关系,整体销毁时部分也会销毁。
用 实心菱形 + 实线箭头 表示,菱形指向整体,箭头指向部分。实现方式:成员变量表示生命周期绑定关系。
class Engine {};
class Car {
private:
Engine engine; // Car 组合了 Engine
}; 继承
- 继承表示一个类是另一个类的子类(派生类),是一种“is-a”关系。
- 子类继承父类的所有公开和保护成员。
用 实线空心三角箭头 表示,箭头从子类指向父类。实现方式:C++ 中使用类的继承
class Parent {};
class Child : public Parent {}; // Child 继承了 Parent 实现
- 实现表示类实现一个接口,是继承关系的特殊形式。
- 子类需要实现接口中定义的所有纯虚函数。
用 虚线空心三角箭头 表示,箭头从实现类指向接口。实现方式:C++ 中使用抽象类或纯虚函数。
class Interface {
public:
virtual void func() = 0; // 纯虚函数
};
class Implementation : public Interface {
public:
void func() override {
// 实现接口方法
}
};
1. 依赖(Dependency)
- 定义:方法依赖另一个类的对象,但不长期持有其引用。
- 示例:打印机依赖文档
Document,但Printer不会存储Document。
class Document {
public:
void showContent() { std::cout << "This is a document." << std::endl; }
};
class Printer {
public:
void print(Document& doc) { // 依赖关系:方法参数依赖 Document
doc.showContent();
}
};
int main() {
Document doc;
Printer printer;
printer.print(doc); // 依赖 Document 进行打印
} 🔹 特点:Printer 只在 print() 方法调用时使用 Document,不会持有它的引用。
2. 关联(Association)
- 定义:一个类知道另一个类的存在,但不拥有它的生命周期。
- 示例:学生(
Student)知道老师(Teacher),但Teacher不是Student的一部分。
class Teacher {
public:
void teach() { std::cout << "Teaching..." << std::endl; }
};
class Student {
private:
Teacher* teacher; // 关联关系:Student 只是持有 Teacher 的指针
public:
void setTeacher(Teacher* t) { teacher = t; }
void study() { teacher->teach(); }
};
int main() {
Teacher t;
Student s;
s.setTeacher(&t); // 关联 Student 和 Teacher
s.study();
} 🔹 特点:Student 仅持有 Teacher 指针,不管理 Teacher 的生命周期。
3. 聚合(Aggregation)
- 定义:一个类包含另一个类的引用,但不控制其生命周期。
- 示例:学校(
School)包含老师(Teacher),但Teacher依然可以独立存在。
#include <vector>
class Teacher {
public:
void teach() { std::cout << "Teacher is teaching." << std::endl; }
};
class School {
private:
std::vector<Teacher*> teachers; // 聚合关系
public:
void addTeacher(Teacher* t) { teachers.push_back(t); }
void startClasses() {
for (auto t : teachers) {
t->teach();
}
}
};
int main() {
Teacher t1, t2;
School school;
school.addTeacher(&t1);
school.addTeacher(&t2);
school.startClasses();
} 🔹 特点:School 不会销毁 Teacher,Teacher 仍然可以独立存在。
4. 组合(Composition)
- 定义:一个类是另一个类的组成部分,整体对象销毁时,部分对象也会销毁。
- 示例:人(
Person)包含心脏(Heart),Heart不能脱离Person独立存在。
class Heart {
public:
void beat() { std::cout << "Heart is beating..." << std::endl; }
};
class Person {
private:
Heart heart; // 组合关系:Heart 由 Person 拥有
public:
void live() { heart.beat(); }
};
int main() {
Person p;
p.live(); // 心脏随人一起存在
} 🔹 特点:Heart 依赖 Person 的生命周期,Person 销毁后,Heart 也随之销毁。
5. 继承(Inheritance)
- 定义:子类继承父类的属性和行为,是 "is-a" 关系。
- 示例:汽车(
Car)继承交通工具(Vehicle)。
class Vehicle {
public:
void move() { std::cout << "Vehicle is moving..." << std::endl; }
};
class Car : public Vehicle {
public:
void honk() { std::cout << "Car is honking!" << std::endl; }
};
int main() {
Car myCar;
myCar.move(); // 继承自 Vehicle
myCar.honk(); // Car 自己的方法
} 🔹 特点:Car 是 Vehicle 的特殊类型,可以继承 Vehicle 的方法。
6. 实现(Realization)
- 定义:类实现了一个接口(抽象类),但 不继承具体实现。
- 示例:鸟(
Bird)实现飞行接口(Flyable)。
class Flyable {
public:
virtual void fly() = 0; // 纯虚函数
};
class Bird : public Flyable {
public:
void fly() override { std::cout << "Bird is flying!" << std::endl; }
};
int main() {
Bird b;
b.fly();
} 🔹 特点:Bird 必须实现 Flyable 的 fly() 方法,否则会编译错误。
总结:六种类关系对比
| 关系类型 | 关键字 | 强度 | 生命周期 | 例子 |
| 依赖(Dependency) | 方法参数 | 弱 | 无影响 | Printer 依赖 Document |
| 关联(Association) | 指针/引用 | 中 | 无影响 | Student 关联 Teacher |
| 聚合(Aggregation) | std::vector<T*> | 较强 | 整体销毁不影响部分 | School 聚合 Teacher |
| 组合(Composition) | 成员变量 | 强 | 整体销毁部分也销毁 | Person 组合 Heart |
| 继承(Inheritance) | class A : public B | 强 | 受父类影响 | Car 继承 Vehicle |
| 实现(Realization) | class A : public Interface | 强 | 受接口影响 | Bird 实现 Flyable |
选择建议:
- 仅方法中使用另一个类(短期关系) ➝ 依赖
- 只需要知道另一个类存在(长期关系) ➝ 关联
- 一个类包含多个对象,但不控制它们的生命周期 ➝ 聚合
- 组成关系(生命周期完全依赖整体) ➝ 组合
- 子类继承父类行为 ➝ 继承
- 类实现接口,提供特定功能 ➝ 实现
类图详解
顺序图详解
协作图详解
状态图详解
活动图详解
构件图详解
部署图详解