封装,继承和多态详解

2023-10-26

封装、继承和多态是 C++ 中三个重要的面向对象编程技术。本文将详细介绍这些技术的概念、原理和用法,以帮助读者更好地理解并应用它们。

一、封装

封装是一种面向对象编程的基本概念,它指的是将数据和方法封装在一个对象内部,防止外部通过对象的公共接口直接访问变量和方法,保持了数据的私密性,减少了对象间的耦合。在 C++ 中,我们可以使用类来实现封装。类中的变量和函数可以使用 public、protected 或 private 进行访问控制,分别表示公共、保护和私有属性。

例如,我们定义一个示例类 Student:

class Student {
public:
    void setID(int id) {
        m_id = id;
    }
    int getID() {
        return m_id;
    }
private:
    int m_id;
};

在上述代码中,setID() 和 getID() 函数分别用于设置和获取学生的 ID 号。通过将 m_id 变量设为私有属性,实现了封装。外部程序无法直接访问 m_id 变量,只能通过 setID() 和 getID() 函数来进行,并且通过.public关键字将这俩函数设为公开的, 用户可以在类的外部访问这些函数。

二、继承

继承是一种通过扩展已有类(即父类)来创建新类(即子类)的机制。子类从父类继承了父类的属性和方法,同时可以添加新属性和方法。这种继承关系形成了对象之间的关联,简化了程序设计,提高了代码的重用性。

例如,我们定义一个示例类 Teacher 继承自 Student:

class Teacher: public Student {
public:
    void setSalary(double salary) {
        m_salary = salary;
    }
    double getSalary() {
        return m_salary;
    }
private:
    double m_salary;
};

在上述代码中,Teacher 类继承自 Student 类,并添加了一个新的属性 m_salary 和相应的访问函数 setSalary() 和 getSalary()。由于 Teacher 类继承了 Student 类,因此在 Teacher 的对象中不仅可以访问它自己的属性和方法,还可以访问 Student 类中已有的属性和方法。

三、多态

多态是一种在不同的对象上调用同名函数的能力,即在运行期根据对象的类型进行动态绑定的机制。构成多态的三个条件分别是:
1.必须存在继承关系;
2.继承关系中必须有同名虚函数,并且是覆盖关系(函数原型相同);
3.存在基类的指针,通过该指针调用虚函数。
C++ 中实现多态的方式有两种:虚函数和函数指针。

1. 虚函数

虚函数是一种在父类中声明的函数,它可以在子类中被重新定义并实现,从而使得在父类的指针或引用上调用该函数时,将根据实际对象类型进行方法动态绑定。虚函数的定义格式为:virtual 返回类型 函数名 参数列表。

例如,我们定义一个 Animal 类,并在其中定义一个虚函数 speak():

class Animal {
public:
    virtual void speak() {
        cout << "Animal is speaking." << endl;
    }
};

接着,我们定义一个 Dog 类,继承自 Animal 类,重定义了 speak() 函数:

class Dog : public Animal {
public:
    void speak() {
        cout << "Dog is barking." << endl;
    }
};

在上述代码中,当我们创建一个 Animal 类的指针或引用,并指向 Dog 类的对象时,调用 speak() 方法时将根据实际对象类型进行动态绑定。因此,执行以下代码得到的输出是 “Dog is barking.”:

Animal* pAnimal = new Dog();
pAnimal->speak();

2. 函数指针

函数指针也可以实现多态的效果。函数指针是指向函数的指针变量,它可以动态地指向不同的函数,从而实现在不同的对象上调用同名函数的能力。在 C++ 中,我们可以定义一个函数指针类型,然后用对象的指针或引用调用该函数指针,从而实现动态绑定。

例如,我们定义一个 Animal 类,并在其中定义一个函数指针类型 fpSpeak 和一个 speak() 函数:

class Animal {
public:
    typedef void(*funcPtr)();
    funcPtr fpSpeak;
    virtual void speak() {
        fpSpeak();
    }
};

接着,我们定义一个 Dog 类,重定义了 fpSpeak 指针和 speak() 函数:

class Dog : public Animal {
public:
    static void dogSpeak() {
        cout << "Dog is barking." << endl;
    }
    Dog() {
        fpSpeak = dogSpeak;
    }
};

在上述代码中,我们将 fpSpeak 指针赋值为 Dog 类中的静态函数 dogSpeak(),并在构造函数中进行了初始化。然后,我们可以创建一个 Animal 类的指针或引用,并指向 Dog 类的对象,调用 speak() 方法时将根据实际对象类型进行动态绑定。因此,执行以下代码得到的输出也是 “Dog is barking.”:

Animal* pAnimal = new Dog();
pAnimal->speak();

四、总结

封装、继承和多态是面向对象编程中重要的三个技术。封装可以保证数据的隐私性和安全性;继承可以提高代码重用性和简化设计过程;多态可以使得函数调用更加灵活和动态。在实际编程中,我们应该结合具体情况,合理运用这些技术来提高代码的可维护性和可扩展性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

封装,继承和多态详解 的相关文章

  • 如何在 C++ 中的文件末尾添加数据?

    我已按照网上的说明进行操作 此代码应该将输入添加到文件 数据库 的末尾 但当我检查时 数据会覆盖现有数据 请帮忙 这是我的代码 int main string name string address string handphone cou
  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • 使用 Unity 在构造函数中使用属性依赖注入

    好的 我在基类中定义了一个依赖属性 我尝试在其派生类的构造函数内部使用它 但这不起作用 该属性显示为 null Unity 在使用 container Resolve 解析实例后解析依赖属性 我的另一种选择是将 IUnityContaine
  • Unix网络编程澄清

    我正在翻阅这本经典书籍Unix网络编程 https rads stackoverflow com amzn click com 0139498761 当我偶然发现这个程序时 第 6 8 节 第 179 180 页 include unp h
  • 如何检查QProcess是否正确执行?

    QProcess process sdcompare QString command sdcompare QStringList args sdcompare command sdcompare diff args sdcompare lt
  • 互斥体实现可以互换(独立于线程实现)

    所有互斥体实现最终都会调用相同的基本系统 硬件调用吗 这意味着它们可以互换吗 具体来说 如果我使用 gnu parallel算法 使用openmp 并且我想让他们称之为线程安全的类我可以使用boost mutex用于锁定 或者我必须编写自己
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • C++:.bmp 到文件中的字节数组

    是的 我已经解决了与此相关的其他问题 但我发现它们没有太大帮助 他们提供了一些帮助 但我仍然有点困惑 所以这是我需要做的 我们有一个 132x65 的屏幕 我有一个 132x65 的 bmp 我想遍历 bmp 并将其分成小的 1x8 列以获
  • 私有模板函数

    我有一堂课 C h class C private template
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • 有人可以提供一个使用 Amazon Web Services 的 itemsearch 的 C# 示例吗

    我正在尝试使用 Amazon Web Services 查询艺术家和标题信息并接收回专辑封面 使用 C 我找不到任何与此接近的示例 所有在线示例都已过时 并且不适用于 AWS 的较新版本 有一个开源项目CodePlex http www c
  • C++ 密码屏蔽

    我正在编写一个代码来接收密码输入 下面是我的代码 程序运行良好 但问题是除了数字和字母字符之外的其他键也被读取 例如删除 插入等 我知道如何避免它吗 特q string pw char c while c 13 Loop until Ent
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • 如何在 C# 中调整图像大小同时保持高质量?

    我从这里找到了一篇关于图像处理的文章 http www switchonthecode com tutorials csharp tutorial image editing saving cropping and resizing htt
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 第2章 应用层-计算机网络

    目录 学习目的 相关概念理解和主流应用层协议学习 目录 应用层协议原理 一些网络应用 了解应用层大概的应用 研发网络应用程序 研发网络应用程序的核心 基于运输层提供的服务 实现可以相互通信的端系统 没有应用程序软件运行在网络核心设备上 网络
  • 大数据专业到底有多火?

    2017 2018大数据为什么这么火热 从以下方面来看 人民日报官方微信公众平台发布了一篇文章 公布已有35所高校获批 数据科学与大数据技术 专业 使大数据受到更多家长的关注 大数据也被越来越多的人重视 高校开办相关专业也不能缓解大数据人才
  • MySQL安装出现环境问题(缺少Microsoft Visual C++ 2019 Redistributable Package)

    在安装MySQL时 选择安装类型 Setup Type 后 需要检查底层环境 一般来说 电脑的环境都是满足要求的 部分电脑可能会存在环境缺失的情况 不同安装模式和版本的环境要求不同 有的一个两个 有的多个 当相关环境缺失时 环境会报错 并显
  • 8.spring系列- java注解

    问题 注解是干什么的 一个注解可以使用多次吗 如何使用 Inherited是做什么的 Target中的TYPE PARAMETER和TYPE USER用在什么地方 泛型中如何使用注解 注解定义可以实现继承吗 spring对注解有哪些增强 A
  • Unity 2022 (Windows 10) 每次打开项目都会弹出"Unity is running as administrator"

    1 Win R 输入 control 打开控制面板 2 找到 用户账户 gt 更改用户账户控制设置 3 将滑块调用中间 仅当应用尝试更改我的计算机时通知我 默认 4 重启电脑
  • python后端学习(四)进程、消息队列、进程池

    进程以及状态 1 进程 程序 例如xxx py这是程序 是一个静态的 进程 一个程序运行起来后 代码 用到的资源 称之为进程 它是操作系统分配资源的基本单元 不仅可以通过线程完成多任务 进程也是可以的 2 进程的状态 工作中 任务数往往大于
  • 【转载】KaTeX 数学公式大全

    文章目录 转载自 前言 受支持的功能 声调记号 定界符 括号之类 定界符大小 5
  • HTML——锚链接

    不同页面锚链接 a href a p a href 锚链接 html shuiguo 水果 a p p a href 锚链接 html shucai 蔬菜 a p p a href 锚链接 html yundong 运动 a p 展示效果
  • [计算机毕业设计]食品安全数据的关联分析模型的应用

    前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度的 对本科同学来说是充满挑战 为帮助大
  • angular6学习(七):样式设置和调用

    样式调用是在app component ts中调用app component css设置 外置调用 也可内置调用 一 外置调用 在html文件中添加h3标签 在css文件中设置h3样式 显示如下 一 内置调用 在 ts文件中设置h3样式 显
  • 远程计算机已加入AAD凭据不工作

    解决方法 计算机需要加入AAD Azure Active Directory 设置 账户 其他用户 连接工作或学校用户 连接 在下方的 替代操作 中选择 将此设备加入 Azure Active Directory 输入用户名和密码 点击加入
  • 学习日记——STM32CubeMX软件应用(2020.1.31)

    STM32CubeMX的定义 STM32CubeMX是ST公司主动原创的一款代码生成工具 它可以减轻开发时间和费用 相当于一种偷懒的做法 STM32CubeMX集成了一个全面的软件平台 支持STM32每一个系列的MCU开发 STM32Cub
  • 【idea】IDEA常用断点详解

    一 断点条件过滤 场景 过滤条件i lt 10 1 标注断点 点击需要调试的代码行 2 鼠标悬浮在断点上 右击 在condition中输入条件 如 i 10 点击done按钮 3 确认条件是否生效 鼠标悬浮断点 显示所填写的条件 4 点击右
  • 搭建个人网站vm+center os+apache

    如何搭建个人网站 准备的前提 vm cnetos 7 apche 在vm上安装center os的教程就不介绍了这个有很多 1 如何配置一台刚装好了center os 7并且能够使他联网 ping 通百度 ip a查看当前ip地址 如果显示
  • 微信小程序:环形进度条模块

    利用canvas实现微信小程序环形进度条模块 模块下载链接 下载链接 最近开发一款背单词的微信小程序 计划使用环形进度条展示每日背单词进度 效果图如下 可渐变颜色 开发步骤 1 在根目录创建名为components的文件夹 用来放需要引用的
  • java链式编程/级联式编程

    链式编程 也叫级联式编程 调用对象的函数时返回一个this对象指向对象本身 达到链式效果 可以级联调用 链式编程 通过高阶函数以点为连接将多个函数连接在一起完成参数传递和复杂的操作 通俗的说是通过点号 链接在一起成为一句代码 链式编程的优点
  • sqli-labs-less-1完整解析,小白干货

    Less 1 Sql知识点 Limit x y 从x 1行开始输出 共输出y行 Order by 排序 asc升序 默认 desc 降序 Union MySQL执行两条SELECT语句 并把输出组合成单个查询结果集 Group concat
  • Java后端返回前端的日期差9小时?

    当后端返回Date类型到前端的时候 需要在实体中增加 JsonFormat注释 这个可以帮我们处理格式化 很多人都是用下面这种写法 JsonFormat locale zh timezone GMT 8 pattern yyyy MM dd
  • win10蓝牙已配对连接不上_Win10系统蓝牙配对手机连接不成功的解决方法

    Win10系统蓝牙配对手机连接不成功的解决方法 很多的Win10用户都在使用蓝牙连接手机 一些网友在连接时出现win10系统蓝牙已配对但连接不成功 出现在这样的问题怎么解决呢 下面我们来看看Win10镜像官网给大家带来的解决方法 Win10
  • 封装,继承和多态详解

    封装 继承和多态是 C 中三个重要的面向对象编程技术 本文将详细介绍这些技术的概念 原理和用法 以帮助读者更好地理解并应用它们 一 封装 封装是一种面向对象编程的基本概念 它指的是将数据和方法封装在一个对象内部 防止外部通过对象的公共接口直