当前位置: 首页 > news >正文

Chapter1—设计模式基础

设计模式基础

1 面向对象基本概念

想要学好设计模式这一课程,我们需要了解一些面向对象编程的一些基本概念。

  • 封装(Encapsulation)

封装是面向对象编程的一个主要特征,它将对象的数据(属性)和操作这些数据的方法(行为)结合在一起,形成一个独立的对象。这样做的好处是可以隐藏内部的复杂性,只暴露有限的接口给外部使用。在Java中,通常通过设置成员变量为私有(private)来实现封装,并提供公共的方法(public methods)来访问和修改这些变量。

  • 继承(Inheritance)

继承允许新创建的类(子类)继承现有类(父类)的属性和方法。这意味着可以在现有类的基础上构建新的类,从而重用和扩展现有代码。在Java中,继承是通过关键字extends来实现的。

  • 多态(Polymorphism)

多态性是指允许不同类的对象对同一消息作出响应的能力。简单来说,就是允许使用父类类型的引用指向子类的对象。这样,同一个接口可以用来调用不同的实现方法,这些方法可能属于不同的类。

封装和继承的概念相对较为简单,多态相对来说比较复杂一点。

2 多态

C++多态(Polymorphism)允许使用基类指针或引用来调用子类的重写方法,从而使得同一接口可以表现不同的行为。

以下是多态的几个关键点:

虚函数(Virtual Functions)

  • 在基类中声明一个函数为虚函数,使用关键字virtual
  • 派生类可以重写(override)这个虚函数。
  • 调用虚函数时,会根据对象的实际类型来决定调用哪个版本的函数。

动态绑定(Dynamic Binding)

  • 也称为晚期绑定(Late Binding),在运行时确定函数调用的具体实现。
  • 需要使用指向基类的指针或引用来调用虚函数,编译器在运行时根据对象的实际类型来决定调用哪个函数。

纯虚函数(Pure Virtual Functions)

  • 一个包含纯虚函数的类被称为抽象类(Abstract Class),它不能被直接实例化。
  • 纯虚函数没有函数体,声明时使用= 0
  • 它强制派生类提供具体的实现。

多态的实现机制

  • 虚函数表(V-Table):C++运行时使用虚函数表来实现多态。每个包含虚函数的类都有一个虚函数表,表中存储了指向类中所有虚函数的指针。
  • 虚函数指针(V-Ptr):对象中包含一个指向该类虚函数表的指针。

使用多态的优势

  • 代码复用:通过基类指针或引用,可以操作不同类型的派生类对象,实现代码的复用。
  • 扩展性:新增派生类时,不需要修改依赖于基类的代码,只需要确保新类正确重写了虚函数。
  • 解耦:多态允许程序设计更加模块化,降低类之间的耦合度。

注意事项

  • 只有通过基类的指针或引用调用虚函数时,才会发生多态。
  • 如果直接使用派生类的对象调用函数,那么调用的是派生类中的版本,而不是基类中的版本。
  • 多态性需要运行时类型信息(RTTI),这可能会增加程序的开销。

程序示例

Worker 基类:

class Worker
{
public:Worker() = default;virtual ~Worker() = default;public:virtual void DoWork() = 0;
};

Coder类继承自Worker类:

 class Coder: public Worker
{
public:Coder() = default;~Coder() = default;public:void DoWork() override;
};void Coder::DoWork()
{qDebug() << "程序员写代码!";
}

Tester类继承自Worker类:

class Tester: public Worker
{
public:Tester() = default;~Tester() = default;public:void DoWork() override;
};void Tester::DoWork()
{qDebug() << "测试测试用例!";
}

测试函数:

void TestPolymorphism()
{Worker* pWorker = nullptr;pWorker = new Coder();pWorker->DoWork();          // 调用Coder的DoWork方法delete pWorker;pWorker = nullptr;pWorker = new Tester();pWorker->DoWork();          // 调用Tester的DoWork方法delete pWorker;pWorker = nullptr;
}

有了多态的基础,我们还需要知道在面向对象编程中,我们类与类之间的一些常见关系,知道它们的UML类图怎么表示,学习设计模式本身不需要系统学习UML课程,但是基本的类图关系还是要会。

3 类间关系

设计模式中涉及到的常见的类之间的关系如下

  • 接口实现关系
  • 继承泛化关系
  • 不可分离组合关系
  • 可分离聚合关系
  • 关联关系
  • 依赖关系

接口实现关系

接口实现关系就是派生类必须重写接口中的所有方法,在UML类图中用"虚线+空心箭头"表示,其中箭头指向基类。
在这里插入图片描述

继承泛化关系

继承泛化关系就是常说的继承关系,派生类继承基类,基类被看作"一般设计",派生类被看作"特俗设计",因此继承泛化关系也被看作一般与特殊的关系,在UML类图中用"实线+实心箭头"表示,其中箭头指向基类。

在这里插入图片描述

不可分离组合关系

不可分离组合关系可以用整体和部分之间的关系来解释,部分是不能脱离整体单独存在的。部分对象与整体对象是不可分离的,一旦整体对象析构,部分对象就会随之消失,它们属于同一个生命周期。不可分离组合关系在UML类中用"实线+实心菱形"表示,其中实心菱形指向整体。

在这里插入图片描述

可分离聚合关系

可分离聚合关系也可以说成是整体与部分的关系,它与不可分离组合关系的区别是,这种整体与部分是可以分离的,也就是说部分是可以脱离整体单独存在的。UML类中用"实线+空心菱形"表示,其中空心菱形指向整体。

在这里插入图片描述

关联关系

关联关系就是一个类与另一个类在对象之间的联系,联系可以是双向的,也可以是单向的。在UML类图中,双向关联关系用没有箭头的实线表示,单向关联关系用"实线+箭头"表示,箭头指向被关联的类。

在这里插入图片描述
在这里插入图片描述

依赖关系

只有在一个类依赖另一个类中的方法时才存在依赖关系,一般将类作为参数传递,通过对方法的调用实现一个类访问另一个类的功能。在UML类图中,使用带箭头的虚线表示这类关系,箭头指向被依赖的类。
在这里插入图片描述


文章转载自:

http://SsJg1Ajd.rrqgf.cn
http://04zbo0Xx.rrqgf.cn
http://CySUsEJc.rrqgf.cn
http://gJ6ZuPKz.rrqgf.cn
http://a5JEFY5w.rrqgf.cn
http://vxUWheGJ.rrqgf.cn
http://Zh3QxgA3.rrqgf.cn
http://RALrCpKB.rrqgf.cn
http://QbQs6S4u.rrqgf.cn
http://iLcXhsLQ.rrqgf.cn
http://eWJvtN7z.rrqgf.cn
http://fQ9RIhrU.rrqgf.cn
http://PnyjnJuy.rrqgf.cn
http://UI0DGQrW.rrqgf.cn
http://fEPKim4a.rrqgf.cn
http://XyPlBDFd.rrqgf.cn
http://VIqV3jls.rrqgf.cn
http://x5mt08Vc.rrqgf.cn
http://PdVe2CMx.rrqgf.cn
http://9ta1UvnX.rrqgf.cn
http://woGxnNDv.rrqgf.cn
http://kW1LOwYd.rrqgf.cn
http://uyyBmYvw.rrqgf.cn
http://bGgb2lT9.rrqgf.cn
http://0Cjw4voM.rrqgf.cn
http://LnNiiikI.rrqgf.cn
http://ifoMuAIq.rrqgf.cn
http://Ybe2LiER.rrqgf.cn
http://zOAJPBuL.rrqgf.cn
http://dZk9lYGA.rrqgf.cn
http://www.dtcms.com/a/364314.html

相关文章:

  • More Effective C++ 条款25:将构造函数和非成员函数虚拟化
  • 外网获取瀚高.NET驱动dll方法和使用案例
  • WSL + VSCode + Git + Node.js 开发环境配置文档
  • uni-app与Vue3,实现3D圆柱形旋转画廊效果
  • 人工智能学习:什么是RNN模型
  • VMware Workstation 磁盘空间不足扩容
  • 二、Scala流程控制:分支与循环
  • C题目训练【三连击】
  • 【正则表达式】 正则表达式有哪些语法?
  • Spring中stereotype注解
  • Shell-AWK详解
  • EasyMeeting-注册登录
  • FART 自动化脱壳框架优化实战:Bug 修复与代码改进记录
  • Linux使用-Linux系统管理
  • 物联网时序数据存储方案:Apache IoTDB 集群部署全流程 + TimechoDB 优势解读
  • Debezium系列之:Flink SQL消费Debezium数据,只消费新增数据,过滤掉更新、删除数据
  • 苍穹外卖项目笔记day03
  • 【ShiMetaPi M4-R1】上手:RK3568B2|开源鸿蒙(OpenHarmony) 应用开发快速上手
  • 开源检索增强生成(UltraRAG)框架
  • KafkaRocketMQ重平衡容灾机制
  • 腾讯开源混元多语言翻译模型—— Hunyuan-MT
  • 【算法--链表】142.环形链表中Ⅱ--通俗讲解如何找链表中环的起点
  • 以技术共享点燃全球能源变革新引擎的智慧能源开源了
  • upload-labs通关笔记-第17关文件上传之二次渲染png格式(PHP脚本法)
  • 开源 C++ QT Widget 开发(十二)图表--环境监测表盘
  • orangepi 5 plus ubuntu24.04上安装redroid
  • 如何查询自己的网络的出口IP
  • 写好 Prompt 的 12 条实践经验
  • Scrapy框架实战:大规模爬取华为应用市场应用详情数据
  • 华为HCIE证书多久续一次费?费用多少?