统一建模语言UML之类图(Class Diagram)(表示|关系|举例)

文章目录

  • 1.UML
  • 2.Class Diagram
    • 2.1 类图的表示
    • 2.2 类间的关系
      • 2.2.1 关联
      • 2.2.2 聚合
      • 2.2.3 组合
      • 2.2.4 泛化(继承)
      • 2.2.5 实现(接口实现)
      • 2.2.6 依赖
    • 2.3 类图的作用

参考:Class Diagram | Unified Modeling Language (UML)
UML是软件设计和面向对象编程中常用的一种标准化建模语言,对于可视化系统结构和功能非常有用,类图有多种不同类型的图:用例图,类图,时序图,活动图和状态图,每类图都有规范的表示,不局限于语言,本文介绍以下内容
(1)UML的图分类
(2)类图的表示
(3)类图的关系
(4)类图的作用

1.UML

Unified Modeling Language(UML)是一种标准化的建模语言,用于在软件系统开发过程中可视化、描述和设计软件的结构与行为。UML 提供了一系列图表,帮助开发人员、系统架构师以及相关人员交流系统的设计和功能。UML 包括许多不同类型的图:

  • 用例图(Use Case Diagram):描述系统的功能需求以及外部参与者的交互
  • 类图(Class Diagram):描述系统的静态结构,展示类、属性、方法以及类之间的关系
  • 时序图(Sequence Diagram):展示对象之间的消息传递顺序,描述时间序列中的动态行为
  • 活动图(Activity Diagram):用于表示系统中的流程和业务逻辑
  • 状态图(State Diagram):描述系统或对象的状态以及状态之间的转换

2.Class Diagram

2.1 类图的表示

在类图中,类用方框表示,每个方框包含三个部分:类名,属性和方法,方框之间的连接线说明这些类的关系。类图提供了系统设计的高级概述,有助于沟通和记录软件的结构。它们是面向对象设计的基本工具,在软件开发生命周期中起着至关重要的作用。

在这里插入图片描述
如图所示的方框为类Car的类图表示

  • Class Name:第一个小框描述了类名,通常放在方框中间加粗,类民首字母大写
  • Attributes:第二个小框介绍了类的属性(字段),包括属性名,属性的可见性和数据类型
  • Methods:第三个小框介绍了类的方法,代表了类的行为函数,包括可见性,返回类型和参数
  • Visibility:可见性表示了属性和方法的可获取水平
    (1)+:public公共,对所有类可见
    (2)-:private私有,仅在类内可见
    (3)#:protected保护,对子类可见
    (4)~:包或默认可见性,对同一包中的类可见
  • Parameter:方法中的参数显示了类之间的信息流动
    (1)in:输入参数是从调用对象(client)到被调用对象(server)的参数
    (2)out:输出参数是从被调用对象(server)到调用对象(client)的参数
    (2)inout:输入输出参数同时作为输入和输出,在client和server之间进行信息流通

2.2 类间的关系

在类图中,类之间的关系有以下几种:
在这里插入图片描述
比较常见的分类是6种:关联,聚合,组合,泛化(继承),实现,依赖,还有一些概念更细分的,比如直接关联,使用依赖等。

关系描述
关联Association表示类之间的长期持久关系,一个类持有另一个类的引用,通常通过成员变量表示
聚合Aggregation整体和部分关系,部分可以独立于整体
组合Composition整体和部分关系,部分不能独立于整体
泛化Generalization子类继承父类属性和方法,可扩展和重写
实现Realization通过抽象类定义接口,客户端和实现解耦
依赖Dependency表示类之间临时的关系,一个类需要短暂使用另一个类的某个功能,通常通过方法调用实现

2.2.1 关联

此处介绍两种:关联和直接关联,由于概念比较类似放在一个小节

(1)关联Association:是泛指两个类之间的关系,可以是双向或单向,也可以是弱耦合的逻辑联系,用直线表示

在这里插入图片描述

关联举例:选课系统中学生和课程之间是双向关联,学生可以注册多门课程,每门课程可以有多个学生,Student类和 Course类存在关联关系,但是并不代表Student类直接引用 Course类的实例。如下面代码所示,student1和course1的实例创建是独立的,但是student1中的enroll方法会用到course1,course1的add_student也会添加student1

class Student:def __init__(self, name):self.name = nameself.courses = []  # 一个学生可以注册多门课程def enroll(self, course):  # 学生注册课程,课程添加学生self.courses.append(course)course.add_student(self)class Course:def __init__(self, title):self.title = titleself.students = []  # 一门课程可以有多个学生def add_student(self, student):  self.students.append(student)# 创建实例
student1 = Student("Alice")
course1 = Course("Math")# 学生注册课程
student1.enroll(course1)

(2)直接关联Direct Association:强调单向依赖关系,一个类直接持有或依赖另一个类的实例,用带单向箭头的直线表示,箭头指向被持有的类。

直接关联是关联的一种更具体的表现,表示类之间有更明确的耦合关系

在这里插入图片描述

直接关联举例:学生和身份证之间存在一种直接关联。每个学生都必须有一个身份证,学生对象直接持有身份证对象。Student类和IDCard类之间有一个单向的直接关联,这是一种更强的依赖关系,表示Student 类的对象必须持有一个 IDCard 类的对象才能正常工作。如下面代码所示,student的实例创建必须用到id_card实例

class IDCard:def __init__(self, card_number):self.card_number = card_numberclass Student:def __init__(self, name, id_card):self.name = nameself.id_card = id_card  # 学生直接持有身份证的引用# 创建身份证实例
id_card = IDCard("123456789")
student = Student("Alice", id_card)# 访问学生的身份证信息
print(student.id_card.card_number)  # 输出: 123456789

2.2.2 聚合

  • 聚合Aggregation:一种特殊的关联形式,表示整体—部分(whole-part)关系,它表示一种更强的关系,其中一个类(整体)包含或由另一个类(部分)组成,在这种关系中,子类可以独立于其父类而存在。用带空心菱形箭头的直线表示,箭头指向整体
    在这里插入图片描述

聚合举例:公司拥有员工,但是员工可以在没有公司的情况下存在。换句话说,公司雇佣了员工,但员工可以辞职并加入另一家公司,因此公司和员工之间的关系是聚合。Company 是整体,Employee 是部分,如下面代码所示,company实例由employee1和employee2实例组成,但是删除company并不会影响employee1和employee2

class Employee:def __init__(self, name):self.name = namedef work(self):print(f"{self.name} is working.")class Company:def __init__(self, name):self.name = nameself.employees = []  # 聚合关系,公司由多个员工组成def hire(self, employee):self.employees.append(employee)print(f"{employee.name} has been hired by {self.name}.")def list_employees(self):print(f"{self.name} has the following employees:")for emp in self.employees:print(f"- {emp.name}")# 创建公司和员工实例
employee1 = Employee("Alice")
employee2 = Employee("Bob")
company = Company("TechCorp")# 公司雇佣员工
company.hire(employee1)
company.hire(employee2)# 公司列出员工
company.list_employees()# 即使公司不存在,员工仍然可以存在
del company
employee1.work()  # 输出: Alice is working.

2.2.3 组合

  • 组合Composition:一种更强的聚合形式,表示更重要的所有权或依赖关系。在组合中,部分类不能独立于整体类而存在。组合带实心菱形箭头的直线表示,箭头指向整体

在这里插入图片描述

组合举例:手机里通讯录和联系人的关系是组合关系,如果通讯录被删除,那么里面的联系人也会删除,也就是说联系人不能独立于通讯录存在。ContactBook 是整体,Contact 是部分

class Contact:def __init__(self, name, phone):self.name = nameself.phone = phonedef display_contact(self):print(f"Name: {self.name}, Phone: {self.phone}")class ContactBook:def __init__(self):self.contacts = []  # 组合关系,通讯录拥有多个联系人def add_contact(self, name, phone):contact = Contact(name, phone)  # 创建联系人的同时,直接把它归属到通讯录self.contacts.append(contact)# 创建通讯录实例
contact_book = ContactBook()# 向通讯录添加联系人
contact_book.add_contact("Alice", "123-456-7890")
contact_book.add_contact("Bob", "987-654-3210")
# 删除通讯录
del contact_book
# 联系人对象也会随之销毁,无法独立存在

2.2.4 泛化(继承)

  • 泛化Generalization(继承Inheritance):表示类之间的“is-a”关系,其中一个类(subclass或child)继承另一个类(supclass或parent)的属性和行为,继承使得子类能够复用父类的代码,同时可以扩展或重写父类的功能。用一条带空心三角箭头的实线表示,箭头指向父类
    在这里插入图片描述

继承举例:一个银行账户下的储蓄账户和信用账户可以共用这个银行账户的信息,BankAccount是父类,SavingsAccount 是子类,CreditAccount 是子类

# 父类:BankAccount
class BankAccount:def __init__(self, account_number, balance):self.account_number = account_number  # 账户号码self.balance = balance  # 账户余额def deposit(self, amount):"""存款方法"""self.balance += amountprint(f"Deposited {amount}. New balance: {self.balance}")def withdraw(self, amount):"""取款方法"""if amount > self.balance:print("Insufficient funds!")else:self.balance -= amountprint(f"Withdrew {amount}. New balance: {self.balance}")# 子类:SavingsAccount
class SavingsAccount(BankAccount):def __init__(self, account_number, balance, interest_rate):super().__init__(account_number, balance)self.interest_rate = interest_rate  # 储蓄账户的利率def add_interest(self):"""添加利息"""interest = self.balance * self.interest_rateself.balance += interestprint(f"Interest added: {interest}. New balance: {self.balance}")# 子类:CreditAccount
class CreditAccount(BankAccount):def __init__(self, account_number, balance, credit_limit):super().__init__(account_number, balance)self.credit_limit = credit_limit  # 信用账户的信用额度def withdraw(self, amount):"""重写父类的取款方法,允许透支"""if amount > self.balance + self.credit_limit:print("Exceeds credit limit!")else:self.balance -= amountprint(f"Withdrew {amount}. New balance: {self.balance}")# 测试代码
savings = SavingsAccount("12345", 1000, 0.05)
savings.deposit(500)
savings.add_interest()credit = CreditAccount("67890", 500, 1000)
credit.withdraw(200)
credit.withdraw(1500)  # 允许透支
credit.withdraw(2000)  # 超过信用额度

2.2.5 实现(接口实现)

  • 实现Realization(接口实现Interface Implementation):是在面向对象设计中,通过接口或抽象类来定义某些功能,来描述某一组行为的约定,而具体的实现由不同的类来完成。可以避免直接依赖具体类,而是依赖接口或抽象类,从而实现代码的解耦。用带空心三角箭头的虚线表示,箭头指向接口
    在这里插入图片描述

实现举例:有一个支付系统,它支持多种支付方式,如信用卡支付,PayPal 支付和比特币支付,每种支付方式都有自己的具体实现方式,但它们都应该符合统一的支付行为,比如 pay()。比如下面代码中,IPayment是一个抽象类,也就是客户端接口,声明了一个pay()方法,但是没有具体实现,而CreditCardPayment,PayPalPayment和BitcoinPayment都会各自具体实现pay(),对于客户端代码process_payment传入任何一个payment_method,都可以使用pay(),客户端代码不关心具体是哪种支付方式,只需要知道它实现了IPayment 接口即可。

from abc import ABC, abstractmethod# 定义一个支付接口(抽象基类)
class IPayment(ABC):@abstractmethoddef pay(self, amount):"""支付方法,所有支付方式都必须实现"""pass# 具体实现:信用卡支付
class CreditCardPayment(IPayment):def pay(self, amount):print(f"Paid {amount} using Credit Card.")# 具体实现:PayPal 支付
class PayPalPayment(IPayment):def pay(self, amount):print(f"Paid {amount} using PayPal.")# 具体实现:比特币支付
class BitcoinPayment(IPayment):def pay(self, amount):print(f"Paid {amount} using Bitcoin.")# 客户端代码,使用支付系统
def process_payment(payment_method, amount):payment_method.pay(amount)# 测试代码
credit_card = CreditCardPayment()
paypal = PayPalPayment()
bitcoin = BitcoinPayment()# 使用不同的支付方式处理支付
process_payment(credit_card, 100)
process_payment(paypal, 200)
process_payment(bitcoin, 300)

这种实现关系可以很容易地为系统添加新的实现方式(如支持新的支付方式),而不需要修改现有代码,新增的实现类只需要实现接口即可,完全可以独立于其他代码进行开发,将客户端代码与具体实现解耦来提高系统的可维护性,如果不使用实现关系,直接让 process_payment 依赖于具体的支付类,那么就会出现下面这种不停维护客户端代码的情况

def process_payment(payment_method, amount):if isinstance(payment_method, CreditCardPayment):payment_method.pay(amount)elif isinstance(payment_method, PayPalPayment):payment_method.pay(amount)elif isinstance(payment_method, BitcoinPayment):payment_method.pay(amount)# 如果以后新增一种支付方式,还要在这里加新的条件分支

2.2.6 依赖

  • 依赖Dependency:表示一个元素对另一个元素的使用或依赖,但这种关系不像关联或继承那么强,它表示类之间更松散的耦合连接,典型场景是类的方法依赖于另一个类的对象作为参数或返回。 用带普通箭头的虚线表示,箭头指向被依赖者
    在这里插入图片描述

依赖举例:办公室工作人员会使用打印机打印东西,OfficeWorker 依赖 Printer,但并没有保存 Printer 的实例,它只在需要打印时使用Printer

class Printer:def print_document(self, document):print(f"Printing: {document}")class OfficeWorker:def __init__(self, name):self.name = namedef do_work(self, document, printer):printer.print_document(document)

使用依赖Usage Denpency是依赖的一种特定形式,表示一个类(client)利用或依赖另一个类(server)来执行某些任务或访问某些功能。client类依赖于server类提供的服务,但不拥有或创建其实例,上面的打印机例子也是一种使用依赖,此处不再细分描述

2.3 类图的作用

  • 建模类结构:类图通过表示类及其属性、方法和关系,帮助对系统结构进行建模,提供了系统架构的清晰而有条理的视图
  • 理解关系:类图描绘了类之间的关系,例如关联、聚合、组合、继承和依赖关系,有助于开发设计等人员了解系统结构
  • 实施蓝图:类图是软件实施的蓝图,通过说明类、它们的属性、方法及其之间的关系来指导开发人员编写代码
  • 代码生成:一些软件开发工具和框架支持从类图生成代码,开发人员可以从可视化表示中生成大量代码,从而减少手动错误的可能性并节省开发时间
  • 识别抽象和封装:类图能识别抽象以及在类中封装数据和行为,支持面向对象设计的原则,例如模块化和信息隐藏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53716.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据新视界 --大数据大厂之Flink强势崛起:大数据新视界的璀璨明珠

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

electron react离线使用monaco-editor

1.安装monaco-editor/react和monaco-editor pnpm i monaco-editor/react pnpm i monaco-editor 2.引入并做monaco-editor离线配置 import Editor, { DiffEditor, useMonaco, loader } from monaco-editor/react import * as monaco from monaco-editor import editorWorke…

软考 -- 软件设计师 -- 二轮复习(3) -- 数据结构(持续更新)

软考 – 软件设计师 – 二轮复习(3) – 数据结构(持续更新) 文章目录 软考 -- 软件设计师 -- 二轮复习(3) -- 数据结构(持续更新)前言一、时间、空间复杂度二、递归式时间复杂度三、线性表四、栈五、栈和队列六、串七、朴素模式匹配八、KMP模式匹配九、数组十、矩阵十一、树、二…

HarmonyOS开发实战( Beta5.0)自定义装饰器实践规范

介绍 本示例介绍通过自定义装饰器在自定义组件中自动添加inspector (布局回调)方法并进行调用。 效果图预览 不涉及 使用说明 在自定义组件上添加自定义装饰器CallbackObserver,并根据参数设置对应的方法名和需要绑定的组件的ID。编译工程,可以根据…

四款音频剪辑软件免费使用,你更pick哪一个?

视频剪辑知随着软件的不断更新,入门门槛和操作难度也随之变得越来越低,但是依然有不少人不知道剪辑视频要用什么工具,作为一个视频剪辑爱好者,我尝试过不少编辑软件,今天就来跟大家分享一下四款视频剪辑软件在实际使用…

通用四期ARM架构银河麒麟桌面操作系统V10【安装、配置FTP客户端】

一、操作环境 服务端:银河麒麟桌面操作系统V10SP1 客户端:银河麒麟桌面操作系统V10SP1 二、服务端配置 注:以下命令均在终端执行 鼠标点击桌面右键,选择打开终端 操作步骤: 1、安装vsftpd软件:如果提…

深入理解TCP三次握手

在网络通信中,TCP(Transmission Control Protocol,传输控制协议)是一个可靠的、面向连接的协议,它保证了数据包的顺序和完整性。为了建立一个稳定的连接,TCP 使用了一个被称为 三次握手(Three-W…

滑动窗口(1)_长度最小的子数组

个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 滑动窗口(1)_长度最小的子数组 收录于专栏【经典算法练习】 本专栏旨在分享学习C的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 1. …

一款高效、简洁的帧动画生成工具

在现代网页设计和移动应用开发中,帧动画是一种常见的动画实现方式,它通过连续显示一系列静态图片来模拟动画效果。然而,手动创建和管理这些帧动画图片不仅耗时费力,而且效率低下。为此,gka 应运而生,它是一…

Java学习Day41:骑龙救!(springMVC)

springMVC与sevlet都是对应表现层web的,但是越复杂的项目使用SpringMVC越方便 基于Java实现MVC模型的轻量级web框架 目标: 小案例: 1.导入依赖 spring-context: 提供 Spring 框架的核心功能,如依赖注入、事件发布和其他应用上…

无人机之伯努利定律

无人机的伯努利定律是解释无人机飞行原理的关键理论之一,它主要阐述了流体(如空气)在流动过程中速度与压力之间的关系。以下是对无人机伯努利定律的详细解释: 一、伯努利定律的基本原理 伯努利定律是流体力学中的一个基本原理&am…

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件 本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用r…

Word 脚注与正文之间的空行怎么删除啊?

全网都搜索不到解决方案,难道只有我一个人遇到这个问题了吗? 无语,。、;

Java导入、导出excel保姆级教程(附封装好的工具类)

前言 我们在日常开发中,一定遇到过要将数据导出为Excel的需求,那么怎么做呢?在做之前,我们需要思考下Excel的组成。Excel是由四个元素组成的分别是:WorkBook(工作簿)、Sheet(工作表)、Row(行)、Cell(单元格)&#xff…

linux入门到实操-1 Linux概述、诞生过程、发行版本,如何安装?

教程来源:B站视频BV1WY4y1H7d3 3天搞定Linux,1天搞定Shell,清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料,供大家学习交流下载:夸克网盘分享 本文内容为完整笔记的入门篇 概述部分历史内容…

使用LSTM(长短期记忆网络)模型预测股票价格的实例分析

一:LSTM与RNN的区别 LSTM(Long Short-Term Memory)是一种特殊的循环神经网络(RNN)架构。LSTM是为了解决传统RNN在处理长序列数据时遇到的梯度消失或梯度爆炸问题而设计的。 在传统的RNN中,信息通过隐藏状…

使用虚拟信用卡WildCard轻松订阅POE:全面解析平台功能与订阅方式

POE(Platform of Engagement)是一个由Quora推出的人工智能聊天平台,汇集了多个强大的AI聊天机器人,如GPT-4、Claude、Sage等。POE提供了一个简洁、统一的界面,让用户能够便捷地与不同的AI聊天模型进行互动。这种平台的…

基于SpringBoot的社团管理系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于JavaSpringBootVueMySQL的社团管理系统【附源码文档】、…

HashTable哈希表

概念 散列表(Hash Table),又称哈希表。是一种数据结构,特点是:数据元素的关键字与其存储地址直接相关 在顺序结构以及树型结构中,数据元素的关键字与其存储位置没有对应的关系,因此在查找一个元素时,必须要经过关键码…

Windows 平台安装 Nacos 2.x

环境准备 64 位操作系统,Windows 10 / Linux Centos 7JDK 1.8 安装包下载 安装包下载官方地址:https://github.com/alibaba/nacos/releases 启动 将安装包解压到安装的目录下,改名为 nacos-2.0.4。然后进行到 bin 目录下,打开…