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++中的一个重要特性,被广泛应用于面向对象编程中。在实际开发中,继承被广泛用于代码复用和扩展性设计。

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

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

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript基础知识点总结:从零开始学习JavaScript(六)

本章内容主要让小伙伴们自主练习 &#xff0c;建议大家先自己写出来答案&#xff0c;然后对照我的&#xff01;&#xff08;题不难主要培养自己的编程思维&#xff01;&#xff01;&#xff01;&#xff09; 如果大家感感兴趣也可以去看&#xff1a; &#x1f389;博客主页&…

matlab导出高清图片,须经修改后放入latex(例如添加文字说明,matlab画图不易操作)

一、背景 我们在写文章时&#xff0c;使用matlab画图后&#xff0c;如果不需要对图片进行额外修改或调整&#xff0c;例如添加文字说明&#xff0c;即可直接从matlab导出eps格式图片&#xff0c;然后插入到latex使用。 通常latex添加图片&#xff0c;是需要eps格式的。 但很…

两种汇编的实验

week04 一、汇编-1二、汇编-2 一、汇编-1 1 通过输入gcc -S -o main.s main.c -m32 将下面c程序”week0401学号.c“编译成汇编代码 int g(int x){ return x3; } int f(int x){ int i 学号后两位&#xff1b; return g(x)i; } int main(void){ return f(8)1; } 2. 删除汇编代码…

vr体验馆用什么软件计时计费,如遇到停电软件程序如何恢复时间

vr体验馆用什么软件计时计费&#xff0c;如遇到停电软件程序如何恢复时间 一、软件程序问答 如下图&#xff0c;软件以 佳易王vr体验馆计时计费软件V17.9为例说明 1、软件如何计时间&#xff1f; 点击相应编号的开始计时按钮即可 2、遇到停电再打开软件时间可以恢复吗&…

跨域是什么,如何解决跨域

文章目录 前言一、 什么是跨域&#xff1f;二、常见跨域问题三、如何解决跨域如何解决跨域&#xff08;方式&#xff09;前端解决跨域问题CORS反向代理JSONP 总结 前言 跨域是在开发中经常遇到的问题&#xff0c;那什么是跨域呢&#xff1f;及常见跨域的处理方案有哪些呢&…

深入了解云原生:定义与特征解析

文章目录 一、云原生概述1.1 什么是云原生1.2 云原生组成要素1.3 补充资料 二、云原生的目标2.1 云原生关键目标2.2 云原生特性 三、云原生应用 VS 传统单体应用参考资料 一、云原生概述 1.1 什么是云原生 (1)云原生定义 云原生(Cloud Native) 是一种软件架构和开发方法论&a…

D1671 75Ω视频放大驱动芯片 ,2.8~5.5V 应用于手持设备中 内 置 SAG端 子 6dB放 大 器 电 路

D1671 是 一 块 带 4 级 低 通 滤 波 的 单 通 道 视 频 放 大 电 路 &#xff0c; 可 在 3V 或 5V的 低 电 压 下 工 作 。 该 电 路 用 在 有 TV 影 象 输 出 功 能 的 产 品 上 面 &#xff0c; 比 如 机 顶 盒 &#xff0c;监 控 摄 象 头 &#xff0c;DVD &#xff1b;此 …

JSON 详解

文章目录 JSON 的由来JSON 的基本语法JSON 的序列化简单使用stringify 方法之 replacerstringify 方法之 replacer 参数传入回调函数stringify 方法之 spacestringify 方法之 toJSONparse 方法之 reviver 利用 stringify 和 parse 实现深拷贝 json 相信大家一定耳熟能详&#x…

WebGL以及wasm的介绍以及简单应用

简介 下面主要介绍了WebGL和wasm,是除了html,css,js以外Web标准所支持的另外两个大件 前者实现复杂的图形处理,后者提供高效的代码迁移以及代码执行效率 WebGL 简介 首先,浏览器里的游戏是怎么做到这种交互又显示不同的画面的? 试想用我们的前端三件套实现一下.好像可以…

HackTheBox - Medium - Linux - Bagel

Bagel 今天我开始了《Red Team Development and Operations A Practical Guide》的学习&#xff0c;保持学习&#xff0c;后面差不多到时机后就学CRTOⅡ Bagel 是一款中等难度的 Linux 机器&#xff0c;其特点是电子商店容易受到路径遍历攻击&#xff0c;通过该攻击可以获取应…

ZigBee协议栈 -- Zstack协议栈(Zstack2.5.1a)

文章目录 Zstack 协议栈介绍ZStack 的安装ZStack 的结构系统初始化启动操作系统 设备的选择定位编译选项ZStack 中的寻址ZStack 中的路由OSAL 调度管理ZStack 中的串口通信设置配置信道配置 PANID 和要加入的网络最大有效载荷大小非易失性存储器 Zstack 协议栈介绍 CC2530 芯片…

【华为机试】2023年真题B卷(python)-计算最大乘积

一、题目 题目描述&#xff1a; 给定一个元素类型为小写字符串的数组&#xff0c;请计算两个没有相同字符的元素长度乘积的最大值&#xff0c;如果没有符合条件的两个元素&#xff0c;返回0。 二、输入输出 输入描述: 输入为一个半角逗号分隔的小写字符串的数组&#xff0c;2 &…

Collections

Collections Collections四种对集合进行排序的方式 方法名说明public static <T extends Comparable<? super T>> void sort (List<T> list)排序public static void reverse(List<?> list)逆序public static void shuffle(List<?> list)随机…

使用element中el-cascader级联选择器实现省市区街道筛选(非动态加载)

<template><el-form ref"form" :model"form" label-width"80px"><el-form-item label"地址:" prop"addressList"><el-cascaderv-model"form.addressList":props"props":options&q…

golang第一卷---go入门

go入门 对于使用go的好处环境变量配置开发工具 参考网站 &#xff1a;go入门 对于使用go的好处 简单好记的关键词和语法。轻松上手&#xff0c;简单易学。更高的效率。比Java&#xff0c;C等拥有更高的编译速度&#xff0c;同时运行效率媲美C&#xff0c;同时开发效率非常高。…

分布式技术之数据分布方式

文章目录 数据分布设计原则数据分布方法哈希一致性哈希带有限负载的一致性哈希带虚拟节点的一致性哈希四种数据分布方法对比 在分布式系统中&#xff0c;具体是如何实现数据索引或数据分布的呢&#xff1f;目前最常用的方法就是哈希和一致性哈希。 数据分布设计原则 数据分布…

swift-碰到的问题

如何让工程不使用storyboard和scene 删除info.plist里面的Application Scene mainifest 删除SceneDelegate.swift 删除AppDelegate.swift里面的这两个方法 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession…

2012年第一届数学建模国际赛小美赛B题大规模灭绝尚未到来解题全过程文档及程序

2012年第一届数学建模国际赛小美赛 B题 大规模灭绝尚未到来 原题再现&#xff1a; 亚马逊是地球上现存最大的雨林&#xff0c;比地球上任何地方都有更多的野生动物。它位于南美洲大陆的北侧&#xff0c;共有9个国家&#xff1a;巴西、玻利维亚、厄瓜多尔、秘鲁、哥伦比亚、委…

竞赛保研 基于卷积神经网络的乳腺癌分类 深度学习 医学图像

文章目录 1 前言2 前言3 数据集3.1 良性样本3.2 病变样本 4 开发环境5 代码实现5.1 实现流程5.2 部分代码实现5.2.1 导入库5.2.2 图像加载5.2.3 标记5.2.4 分组5.2.5 构建模型训练 6 分析指标6.1 精度&#xff0c;召回率和F1度量6.2 混淆矩阵 7 结果和结论8 最后 1 前言 &…

ppp会话建立的第二阶段:ppp认证

ppp认证的两种协议&#xff1a; pap 密码认证协议&#xff1a;是一种简单的明文认证&#xff0c;使用两次握手建立身份验证。如果碰到动态攻击&#xff0c;pap认证不会断开。一旦pap认证通过&#xff0c;就不会断开chap 挑战握手验证协议&#xff1a;通过三次握手的方式进行MD…