C++的面向对象学习(7):面向对象编程的三大特性之:继承

文章目录

  • 前言
  • 一、继承:继承的类除了拥有上一级类的共性,也拥有自己的特性。
  • 二、继承方式:公有继承(public inheritance)、私有继承(private inheritance)和保护继承(protected inheritance)
    • 1.公共继承
    • 2.保护继承
    • 3.私有继承
  • 三、子类实例化对象后,父类继承的成员哪些属于子类对象?
  • 四、子类继承了父类后,子类的构造与析构函数怎么被继承使用呢?
    • 1.继承的构造函数与析构函数执行顺序?
    • 2.父类如果写了构造函数,子类怎么写构造函数呢?
  • 五、父类子类出现同名成员变量处理方式
  • 六、多继承:一个类继承多个类
    • 1.语法:class 子类 : 继承方式 父类1, 继承方式 父类2
    • 2.缺点:如果不同父类存在变量或者函数重名的情况,子类就必须用作用域::来指定。可能会引起命名冲突和二义性问题。
  • 七、菱形继承方式
  • 总结:继承的重要性


前言

前面几节学的基本是两块内容:第一块是C++的一些特性,比如重载、引用、函数参数值传递与地址传递。第二块是面向对象编程的三大特性的其一:封装。封装中涉及了格式、成员变量和成员函数、访问权限、实例化对象、构造函数与析构函数、成员变量与成员函数的存储位置、this指针、友元声明、operator声明的运算符重载等知识。

现在就要接触到面向对象编程的三大特性的其二:继承。

一、继承:继承的类除了拥有上一级类的共性,也拥有自己的特性。

继承的主要优势在于代码的重用性和扩展性。通过继承,子类可以直接使用父类的属性和方法,无需重新编写相同的代码。这样可以减少代码的冗余,并提高代码的可维护性。同时,子类还可以在继承的基础上添加自己的特性,以满足特定的需求

在继承关系中,父类通常是一个更通用、抽象的类,而子类则是在父类基础上进行特化和扩展的类。子类可以通过继承获得父类的属性和方法,并且可以添加新的属性和方法,或者重写父类的方法以实现自己的逻辑。

继承还可以形成类的层次结构,使得代码的组织更加清晰和易于理解。通过继承,可以将类按照其关系进行分类和组织,形成一个类的层次结构,从而更好地组织和管理代码。
举个例子:

#include <iostream>
using namespace std;class Animal {
protected:string name;public:Animal(string name) {this->name = name;}void speak() {cout << "动物发出声音" << endl;}
};class Dog : public Animal {
private:string breed;public:Dog(string name, string breed) : Animal(name) {this->breed = breed;}void speak() {cout << "汪汪汪!" << endl;}void fetch() {cout << "狗狗正在追逐球" << endl;}
};int main() {Animal animal("动物");animal.speak();  // 输出:动物发出声音Dog dog("旺财", "哈士奇");dog.speak();  // 输出:汪汪汪!dog.fetch();  // 输出:狗狗正在追逐球return 0;
}

Animal类是父类,它有一个name属性和一个speak方法。Dog类是子类,它继承了Animal类,并且添加了一个新的属性breed(品种)和一个新的方法fetch(追逐)。

继承的语法:
class 子类: 继承方式 父类

子类也叫派生类,父类也叫基类。

二、继承方式:公有继承(public inheritance)、私有继承(private inheritance)和保护继承(protected inheritance)

在这里插入图片描述

1.公共继承

使用关键字public来指定继承方式。
子类继承了父类的公开成员和保护成员,但不继承父类的私有成员(即不能访问)。
父类的公开接口成员函数既可以让外部调用,也可以让子类调用。

2.保护继承

使用关键字protected来指定继承方式。
子类继承父类的公开成员和保护成员,且在子类中都变为保护成员,父类的私有成员仍然不能访问
父类的接口函数限制在子类和子类的派生类中,外部无法直接访问父类的成员

3.私有继承

使用关键字private来指定继承方式。
子类继承父类的公开成员和保护成员,且在子类中都变为私有成员,父类的私有成员仍然不能访问
私有继承将父类的接口隐藏起来,子类不能直接访问父类的成员函数,只能通过子类自己的公有成员或者友元函数来间接访问。

在这里插入图片描述
子类中无法访问父类私有的权限,但是可以访问公开和受保护的权限。
有几个注意的地方:
①保护权限的成员,只能在子类内部访问,而不能在外部的主函数里访问。
子类继承父类的protected变量,不能在主函数里用对象调用吗?
保护成员可以在子类内部和子类对象中访问,但不能在类外部直接访问。

②子类继承父类后,孙子类应该继承子类的哪些成员呢?
答:当子类继承父类后,孙子类会继承子类的所有成员,包括公有成员、保护成员和私有成员。孙子类可以直接访问子类的公有成员和保护成员,但无法直接访问子类的私有成员。继承的层次可以一直延续下去,每个子类都可以成为下一个子类的父类。

三、子类实例化对象后,父类继承的成员哪些属于子类对象?

在这里插入图片描述
儿子类继承了父类的三个不同权限的成员变量,自己有一个独特的成员变量,那sizeof(son)的结果到底是多少呢?
答案是子类的对象拥有了这四个变量的空间,即使父类有一个私有变量,子类只是不能访问,但实例化对象时也开辟了它的空间。

四、子类继承了父类后,子类的构造与析构函数怎么被继承使用呢?

1.继承的构造函数与析构函数执行顺序?

构造函数的继承:子类会继承父类的构造函数。当创建子类对象时,会先调用父类的构造函数,然后再调用子类自身的构造函数。这样可以确保父类的成员被正确初始化。

析构函数的继承:子类会继承父类的析构函数。当子类对象被销毁时,会先调用子类自身的析构函数,然后再调用父类的析构函数。这样可以确保父类的资源被正确释放。

2.父类如果写了构造函数,子类怎么写构造函数呢?

class father {
private:string name;int age;
protected:int money;
public:father() {name = "xiaogang";age = 38;money = 6000;address = "nanjing";}string address;
};

子类:

class son :public father {
public:son() {money = 5000;address = "beijing";height = 150;}int height;
};

也就是说,父类的构造函数在父类写好后,子类继承时就不能用默认构造函数去实例化对象了,而是要重新写一个含参的构造函数。

一定要注意一点:
子类的对象和父类的对象是完全不同的两个对象,他们各自的成员变量的地址是不同的。构造函数里面的赋值,也只是给自己的对象的成员变量赋值而已

int main() {father f;son son1;cout << son1.address << endl;//儿子是北京cout << f.address << endl;//父亲是南京return 0;
}

五、父类子类出现同名成员变量处理方式

举个例子,父类有个成员变量叫friends,子类也有一个成员变量叫friends。任何通过子类的对象去访问父类的同名成员变量呢?
使用作用域声明:

son1.father::friends
class father {
private:string name;int age;
protected:int money;
public:father() {name = "xiaogang";age = 38;money = 6000;address = "nanjing";friends = "limiing";}string address;string friends;
};class son :public father {
public:son() {money = 5000;address = "beijing";height = 150;friends = "xiaohong";}int height;string friends;
};int main() {father f;son son1;cout << son1.father::friends << endl;return 0;
}

对象son1调用了父亲作用域下的成员变量。

六、多继承:一个类继承多个类

1.语法:class 子类 : 继承方式 父类1, 继承方式 父类2

比如:class C : public A, public B

#include <iostream>
using namespace std;// 基类A
class A {
public:void displayA() {cout << "This is class A" << endl;}
};// 基类B
class B {
public:void displayB() {cout << "This is class B" << endl;}
};// 派生类C,继承自类A和类B
class C : public A, public B {
public:void displayC() {cout << "This is class C" << endl;}
};int main() {C c;c.displayA();  // 调用继承自类A的成员函数c.displayB();  // 调用继承自类B的成员函数c.displayC();  // 调用派生类C自己的成员函数return 0;
}

2.缺点:如果不同父类存在变量或者函数重名的情况,子类就必须用作用域::来指定。可能会引起命名冲突和二义性问题。

七、菱形继承方式

在这里插入图片描述

总结:继承的重要性

继承是C++中的一个重要特性,被广泛应用于面向对象编程中。在实际开发中,继承被广泛用于代码复用和扩展性设计。

下面是一些继承的常见应用场景:

实现类的层次结构:通过继承,可以将类组织成层次结构,从而更好地组织和管理代码。

代码复用:通过继承,可以将一个类的成员函数和成员变量复用到另一个类中,从而减少代码量,提高代码的可维护性和可重用性。

多态性:通过继承和虚函数,可以实现多态性,即同一个函数在不同的派生类中具有不同的实现。

接口设计:通过继承和抽象类,可以定义接口,从而实现代码的松耦合和可扩展性。

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

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

相关文章

C练习——爱因斯坦台阶问题(穷举法)

题目&#xff1a;爱因斯坦曾经提出过这样一道有趣的数学题&#xff1a;有一个长阶梯&#xff0c;若每步上2阶&#xff0c;最后剩下1阶&#xff1b;若每步上3阶&#xff0c;最后剩2阶&#xff1b;若每步上5阶&#xff0c;最后剩下4阶&#xff1b;若每步上6阶&#xff0c;最后剩5…

排序算法讲解

1&#xff09;排序思想&#xff1a; 2&#xff09;排序代码&#xff1a; 3&#xff09;注意点&#xff1a; 4&#xff09;时间/空间复杂度和稳定性 下面的排序是以实现升序讲解的。 &#xff08;一&#xff09;直接插入排序 1&#xff09;排序思想&#xff1a; 把待排序的…

Java注解学习,一文掌握@Autowired 和 @Resource 注解区别

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

Python教程(19)——python异常处理

异常处理 什么是异常异常处理方式try-except语句捕获异常类型 相关的异常类型 什么是异常 在计算机编程中&#xff0c;异常&#xff08;Exception&#xff09;是指在程序执行过程中发生的错误或异常情况。当出现异常时&#xff0c;程序无法正常继续执行&#xff0c;因此需要采…

【Java进阶篇】SimpleDateFormat是线程安全的吗? 使用时应该注意什么?

SimpleDateFormat是线程安全的吗?使用时应该注意什么? ✔️ 典型解析✔️拓展知识仓✔️SimpleDateFormat用法✔️日期和时间模式表达方法✔️输出不同时区的时间✔️SimpleDateFormat线程安全性✔️问题重现✔️线程不安全原因✔️如何解决✔️使用局部变量✔️加同步锁✔️…

Java Log 学习笔记

参考文章&#xff1a; 1.Java 日志从入门到实战 2.Java日志框架的发展历史&#xff0c;你不想了解一下吗 背景 想自定义 logback 配置文件进行日志分级别记录到不同文件&#xff0c;遇到了几个问题&#xff08;使用的是 spring-boot 构建的项目&#xff0c;spring-boot 版本为…

深度学习从入门到不想放弃-5

看了一眼这个文章系列,居然第四集是11月5号写的,这25天可见发生了多少事情... 今天我们讲讲特征,算是基础篇的一个番外篇延伸,我省着在后面的文章里写了,怕扰乱了思路 严格来说这个属于基础机器学习领域里的了,我又不讲决策树,贝叶斯,隐马尔可夫啥的(不在这个系列写,…

OPenGL GLSL

shji 数据类型 整型&#xff08;有符号/无符号&#xff09; 浮点数&#xff08;单精度&#xff09; 布尔值 向量类型/矩阵类型 bool bDone false int value 1; unint vale 21u float value 2.1 向量/分量类型 vec2,vec3,vec4 2分量 3 分量 4 分量复电向量 i…

机器学习---随机森林宫颈癌分类

1. 宫颈癌分类 from sklearn import tree from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV from sklearn.pipeline import Pipeline from sklearn.preprocessi…

VistualStudio查看类图UML

点击菜单栏中的工具–》获取工具和功能。 然后在资源管理器中对应的代码中鼠标右键选择查看类图 生成一个ClassDiagram.cd文件就是类图的文件了。 根据需要拖拽就可以生成类图了。

常用的 MySQL 可视化客户端

数据库可视化客户端&#xff08;GUI&#xff09;让用户在和数据库进行交互时&#xff0c;能直观地查看、创建和修改对象&#xff0c;如&#xff1a;表、行和列。让数据库操作变得更方便了。 今天&#xff0c;我们来了解下目前市场上最常用的 MySQL 可视化客户端。 官方&#x…

数据结构期末复习(2)链表

链表 链表&#xff08;Linked List&#xff09;是一种常见的数据结构&#xff0c;用于存储一系列具有相同类型的元素。链表由节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两部分&#xff1a;数据域&#xff08;存储元素值&#xff09;和指针域&#xff08;指…

vscode配置的C++环境

目录 1、下载并安装VScode 2、下载MinGW 3、配置MinGW 3.1添加环境变量 3.2 Vscode配置 3.3测试 1、下载并安装VScode Visual Studio Code - Code Editing. Redefined 2、下载MinGW 在MinGW官网MinGW-w64 - for 32 and 64 bit Windows - Browse /mingw-w64/mingw-w64-r…

List集合格式转换

最近遇到一个任务&#xff1a; 需要把A集合数据转成 B集合的形式&#xff1a; A集合&#xff1a; B集合&#xff1a; 代码&#xff1a; package com.example.juc.test;import com.example.juc.entity.Ld; import com.example.juc.entity.Student;import java.lang.reflect.F…

【Petalinux】制作SD卡 操作系统 启动

Vivado 添加 SD0 导出hdf 制作SD卡 https://mathd.blog.csdn.net/article/details/135217761 【Petalinux】下为空白SD卡建立BOOT&#xff0c;rootfs分区 Petalinux 生成 Petalinux 框架 petalinux-create --type project --template zynq --name sdtest进入 sdtest 文件…

Ksher H5页面支付实例指导 (PHP实现)

前文 背景介绍 前两天&#xff0c;公司的项目&#xff0c;为了满足泰国客户的支付需求&#xff0c;要求使用 Ksher (开时支付) 对接任务突然就给了鄙人&#xff0c;一脸懵 … 通过了解客户的使用场景、以及参考官网指导 发现&#xff1a;Ksher支付 最令人满意的便是 —— 提供了…

【网络安全/CTF】easyphp 江苏工匠杯

本题考察PHP语言相关绕过知识 正文 开门见山给代码 <?php highlight_file(__FILE__); $key1 0; $key2 0;$a $_GET[a]; $b $_GET[b];if(isset($a) && intval($a) > 6000000 && strlen($a) < 3){if(isset($b) && 8b184b substr(md5($b),…

【Java】如何给你的图片添加自定义水印(附完整代码)?

这是一篇关于怎么尽可能的用尽你电脑里的所有字体给你的图片加水印。。。。 先上效果~ 当然这只是其中一部分字体&#xff0c;&#xff0c;&#xff0c;我也是今天才发现我电脑里居然装了那么多字体 好了废话不多说直接上完整代码~ import io.swagger.models.auth.In;import …

循环生成对抗网络(CycleGAN)

一、说明 循环生成对抗网络&#xff08;CycleGAN&#xff09;是一种训练深度卷积神经网络以执行图像到图像翻译任务的方法。网络使用不成对的数据集学习输入和输出图像之间的映射。 二、基本介绍 CycleGAN 是图像到图像的翻译模型&#xff0c;就像Pix2Pix一样。Pix2Pix模型面临…

软件测试/测试开发丨Python 内置库 sys 学习笔记分享

sys 概述 是 Python 自带的内置模块是与 Python 解释器交互的桥梁 sys 使用 常用属性常用方法导入 sys 模块 # 导入sys模块 import sys# 查看sys模块帮助文档 help(sys)# 查看sys模块的属性和方法 print(dir(sys))sys 常用属性 sys.version&#xff1a;返回 Python 解释器…