C++57个入门知识点_27 继承的概念(类的组合关系:将一个类的对象作为另外一个类的成员;类的组合关系的访问;继承的概念:A类是B的儿子;A被称为子类,B被称为父类或者A被称为派生类,B被称为基类)

2023-11-19

我们知道类有三大特性:封装、继承和多态。封装在前面已经介绍完。本篇开始将会介绍继承。继承是在封装基础上的扩展,也是多态的一个承接。

总结:

  1. 类的组合关系:将一个类的对象作为另外一个类的成员 Class CStudent{ ... public:/private: CPerson m_Per ... }
  2. 类的组合关系的访问方法
  • 类对象放到public进行访问,使用stu.m_per.SetGender(123);的方式访问
  • 类对象放到private,使用公共访问权限的函数进行访问:stu.SetGender(123);
  1. 继承:一个类可以继承另外一个类中的东西,即为继承。
  • 继承的概念:A类是B的儿子
  • A被称为子类,B被称为父类或者A被称为派生类,B被称为基类
  • 关系:子类 is-a 父类 (子类是一个父类的…,学生是一个人)
  • 代码形式为:class CStudent :public CPerson

1. 学生管理系统的传统写法


以一个学生管理系统为例, 按照之前的思路,需要创建不同的类,然后将类组合在一起

创建学生类,老师类,这两个类都是有姓名和性别的成员变量,此时就造成了冗余,易造成错误,可能让人嗅到坏坏的味道。

其代码如下:

#include <iostream>

//面向对象:继承
//学生与老师具有人的共有特征

class CStudent {
public:
	CStudent() {
	}

	~CStudent() {
	}

	int GetGender() {
	return m_nGender;
	}

	void SetGender(int nGender) {
		m_nGender= nGender;
	}
private:
	char m_nszName[255];
	int m_nGender;
};

//增加老师管理系统,老师的数据与行为和学生是类似的,但也有学号,老师号的不同
//如果重建一个老师类就会造成冗余,易造成错误
class CTeacher {
public:
	CTeacher() {
	}
	~CTeacher() {
	}

	int GetGender() {
		return m_nGender;
	}

	void SetGender(int nGender) {
		m_nGender = nGender;
	}

private:
	char m_nszName[255];
	int m_nGender;
};

int main(int argc, char* argv[])
{
	CStudent stu;
	return 0;
}

除了学生和老师类,如果需要再增加宿管阿姨的信息,那就得再创建一个类,同样的代码会反复出现,可能就带来问题,如果同类型的一个地方出错,就需要在代码不同位置修改,十分不利于程序编写。

2. 类的组合关系

将一个类的对象作为另外一个类的成员这种关系称之为 类的组合关系

针对上面的问题,如何解决?
解决思路,出现上面的问题的原因是:代码出现了重复,这是因为学生和老师存在共同的部分。
但是除了共性部分,学生可能有学生ID m_nStuID,老师有老师ID m_nTeaID对于相同的代码我们使用代码去描述,不同的地方加以区别

学生和老师共有人的特征(名字和性别),因此将其 重复共有的部分单独提取 出来写出一个人类。将人作为学生和老师类的属性和特点-将一个类的对象作为另外一个类的成员这种关系称之为 类的组合关系

类的组合关系的访问方法

  • 类对象放到public进行访问,使用stu.m_per.SetGender(123);的方式访问
#include <iostream>
class CPerson
{

public:
	CPerson() {
	}

	~CPerson() {
	}

	int GetGender() {
		return m_nGender;
	}

	void SetGender(int nGender) {
		m_nGender = nGender;
	}

private:
	char m_nszName[255];
	int m_nGender;
};

class CStudent {
public:
	CStudent() {
	}
	~CStudent() {
	}
	
	CPerson m_per;//组合关系:将一个类的成员作为另一个类的成员(共用人的共性)
	
private:
	int m_nStuID;
};

//增加老师管理系统,老师的数据与行为和学生是类似的,但也有学号,老师号的不同
//如果重建一个老师类就会造成冗余,易造成错误
class CTeacher {
public:
	CTeacher() {
	}
	~CTeacher() {
	}
	
	CPerson m_per;//组合关系:将一个类的成员作为另一个类的成员(共用人的共性)
	
private:
	int m_nTeaID;
};


int main(int argc, char* argv[])
{
	CStudent stu;
	stu.m_per.SetGender(123);	
	return 0;
}
  • 类对象放到private,使用公共访问权限的函数进行访问:stu.SetGender(123);
#include <iostream>

class CPerson
{
public:
	CPerson() {
	}

	~CPerson() {
	}

	int GetGender() {
		return m_nGender;
	}

	void SetGender(int nGender) {
		m_nGender = nGender;
	}

private:
	char m_nszName[255];
	int m_nGender;
};

class CStudent {
public:
	CStudent() {
	}

	~CStudent() {
	}

	void SetGender(int nGender) {

		m_per.SetGender(nGender);
	}

private:
	CPerson m_per;//组合关系:将一个类的成员作为另一个类的成员(共用人的共性)
	int m_nStuID;
};

//增加老师管理系统,老师的数据与行为和学生是类似的,但也有学号,老师号的不同
//如果重建一个老师类就会造成冗余,易造成错误
class CTeacher {
public:
	CTeacher() {
	}

	~CTeacher() {
	}

private:
	CPerson m_per;//组合关系:将一个类的成员作为另一个类的成员(共用人的共性)
	int m_nTeaID;
};

int main(int argc, char* argv[])
{

	CStudent stu;
	stu.SetGender(123);
	return 0;
}

上面的过程虽然一定程度上实现了公共属性的复用,只是将关系进行了简单的组合,还是有些繁琐。

3. 类的继承


为了使得重复属性的使用更为简单,提出了继承的语法

继承的性质:

  • 继承的概念:A类是B的儿子

  • A被称为子类,B被称为父类或者A被称为派生类,B被称为基类

  • 关系:子类 is-a 父类 (子类是一个父类的…,学生是一个人)
    在这里插入图片描述

  • 代码形式为:class CStudent :public CPerson

#include <iostream>

//面向对象:继承
//学生与老师具有人的共有特征

class CPerson
{

public:
	CPerson() {
	}

	~CPerson() {
	}

	int GetGender() {
		return m_nGender;
	}

	void SetGender(int nGender) {
		m_nGender = nGender;
	}

private:
	char m_nszName[255];
	int m_nGender;
};

class CStudent : public CPerson
{
public:
	CStudent() {
	}
	~CStudent() {
	}

private:
	int m_nStuID;
};

class CTeacher : public CPerson
{
public:
	CTeacher() {
	}
	~CTeacher() {
	}

private:
	int m_nTeaID;
};


int main(int argc, char* argv[])
{

	CStudent stu;
	stu.SetGender(123);
	return 0;
}

运行结果:stu对象调用了父类CPerson中的成员函数
在这里插入图片描述
在这里插入图片描述

4.学习视频地址:C++57个入门知识点_27 继承的概念

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

C++57个入门知识点_27 继承的概念(类的组合关系:将一个类的对象作为另外一个类的成员;类的组合关系的访问;继承的概念:A类是B的儿子;A被称为子类,B被称为父类或者A被称为派生类,B被称为基类) 的相关文章

  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 为什么 std::allocator 在 C++17 中丢失成员类型/函数?

    一边看着std 分配器 http en cppreference com w cpp memory allocator 我看到成员 value type pointer const pointer reference const refer
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • 在 C 中复制两个相邻字节的最快方法是什么?

    好吧 让我们从最明显的解决方案开始 memcpy Ptr const char a b 2 调用库函数的开销相当大 编译器有时不会优化它 我不会依赖编译器优化 但即使 GCC 很聪明 如果我将程序移植到带有垃圾编译器的更奇特的平台上 我也不
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何在 GCC 5 中处理双 ABI?

    我尝试了解如何克服 GCC 5 中引入的双重 ABI 的问题 但是 我没能做到 这是一个重现错误的非常简单的示例 我使用的GCC版本是5 2 如您所见 我的主要函数 在 main cpp 文件中 非常简单 main cpp include
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • WPF/数据集:如何通过 XAML 将相关表中的数据绑定到数据网格列中?

    我正在使用 WPF DataSet 连接到 SQL Server Express XAML 和 C Visual Studio 2013 Express 我从名为 BankNoteBook 的现有 SQL Server Express 数据

随机推荐