IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 类与面向对象的精华:继承【C++继承】 -> 正文阅读

[C++知识库]类与面向对象的精华:继承【C++继承】

引入继承

为什么需要继承?

C++中代码的可重用性通过继承机制来实现。

简单举例

代码演示:

#include <iostream>

using namespace std;

class Student
{
public:
	void study(string course)
	{
		cout << " i am a student , i am learning " << course << endl;
	}

	void eat(string food)
	{
		cout << " i am eating " << food << endl;
	}
};

class Teachers
{
public:
	void tech(string course)
	{
		cout << " i am teacher , i am teaching " << course << endl;
	}

	void eat(string food)
	{
		cout << " i am eating " << food << endl;
	}
};

int main()
{
	return 0;
}

上面代码中,Teachers类Student 类 具有相同的方法 eat ,那么就可以将 eat 方法进行抽象。
抽象

提取 Teachers类Student 类 的公共方法到 Human类,让Teachers类Student 类 继承 Human类 实现代码可重用。
在这里插入图片描述
代码演示:

#include <iostream>

using namespace std;

// C++ 通过继承关系,实现了代码的可重用性。
class Human//父类	共性
{
public:
	void eat(string food)
	{
		cout << " i am eating " << food << endl;
	}
};

class Student :public Human		//子类 是在父类的基础上增加新的功能, 体现的是个性。
{
public:
	void study(string course)
	{
		cout << " i am a student , i am learning " << course << endl;
	}
};

class Teacher :public Human		//子类 是在父类的基础上增加新的功能, 体现的是个性。
{
public:
	void tech(string course)
	{
		cout << " i am teacher , i am teaching " << course << endl;
	}
};

int main()
{
	Student s;
	s.study("C++");
	s.eat("裤带面");
	
	Teacher t;
	t.tech("python");
	t.eat("油泼辣子酸汤面");
	return 0;
}

运行结果:
运行结果
结论:
继承是一种设计的结果,通常是发生于一套类库中的,设计代码重用的方式。
这种关系是一种设计而为之,不是想继承,就可随便继承的。

继承

定义

类的继承,是新的类从已有类那里得到已有的特性。
从已有类产生新类的过程就是类的派生。

子类  -->	继承  -->	父类		[继承关系]
基类  --> 	派生  -->	派生类   [派生关系]

定性 is-a 而不是 has-a

is-a

is-a 是一种属于关系。

例如:
狗属于一种动物。
可以设计一个 Animal 类,Dog 类作为Animal 类(基类)的派生类;

车属于一种交通工具,在面向对象中表现为一种继承关系。
设计一个 Vehicle 类,Car 类作为 Vehicle 类(基类)的派生类。

has-a

has-a 是一种包含、组合关系。
例如:
车包含方向盘、轮胎、发动机。
但不能说方向盘/轮胎/发动机是一种车。
正确的应该说车聚合(包含)了方向盘、轮胎、发动机。

狗包含腿、尾巴。
但不能说腿、尾巴是一种狗。

如果 A is a B,则 B 是 A 的基类,A 是 B 的派生类。为继承关系。
如果 A 包含 B,则 B 是 A 的组成部分,为聚合关系,可以由组成部分聚合成为一个类。

语法

class 派生类名:[继承方式] 基类名
{
	派生类成员声明;
};

默认的继承方式是 private 私有继承。

一个派生类可以同时有多个基类,这种情况称为多重继承。
派生类只有一个基类,称为单继承。

继承方式

继承方式影响了什么?

继承方式规定了子类如何访问从基类继承的成员。
继承方式有 public, private, protected。
继承方式不影响派生类的访问权限,影响了从基类继承而来的成员的访问权限,包括派生类内的访问权限和派生类对象的访问权限。
代码演示:

#include <iostream>

using namespace std;

class Base
{
public:
	int pub;
	//pretected 对于外界访问属性来说,等同于私有,但可以派生类中可见。
protected:
	int pro;
private:
	int pri;
};

class Drive :public Base
{
public:
	void func()//子类中的访问属性
	{
		pub = 10;
		pro = 100;
		pri = 1000;
	}
public:
	int a;
protected:
	int b;
private:
	int c;
};

int main()
{
	Base b;
	b.pub = 10;		子类对象的访问属性
	b.pro = 100;	//编译器报错,不可访问
	b.pri = 1000;	//编译器报错,不可访问
	return 0;
}

编译器报错:
编译器报错

公有继承 public

基类的公有成员和保护成员在派生类中保持原有访问属性,其私有成员仍为基类的私有成员。

私有继承 private

基类的公有成员和保护成员在派生类中成了私有成员,其私有成员仍为基类的私有成员。

保护继承 protected

基类的公有成员和保护成员在派生类中成了保护成员,其私有成员仍为基类的私有成员。

继承方式结论

结论

派生类的组成

组成图示

派生类中的成员,包含两大部分,一类是从基类继承过来的,一类是自己增加的成员。
从基类继承过过来的表现其共性,而新增的成员体现了其个性。

派生类的组成

说明

全盘接收,除了构造器与析构器。
基类有可能会造成派生类的成员冗余,所以说基类是需设计的。
派生类有了自己的个性,使派生类有了意义。

sizeof(父类 / 子类)

代码演示:

#include <iostream>

using namespace std;

class Base
{
public:
	int pub;
	//pretected 对于外界访问属性来说,等同于私有,但可以派生类中可见。
protected:
	int pro;
private:
	int pri;
};

class Drive :public Base
{
public:
	void func()//子类中的访问属性
	{
		pub = 10;
		pro = 100;
		//pri = 1000;
	}
public:
	int a;
protected:
	int b;
private:
	int c;
};

int main()
{
	cout << "sizeof(Base) = " << sizeof(Base) << endl;
	cout << "sizeof(Drive) = " << sizeof(Drive) << endl;
	return 0;
}

运行结果:
运行结果

继承的内存模型

#include <iostream>
#include <typeinfo>

using namespace std;

class A
{
public:
	A()
	{
		cout << this << endl;
		cout << typeid(this).name() << endl;
	}

	int a;
};

class B :public A
{
public:
	B()
	{
		cout << this << endl;
		cout << typeid(this).name() << endl;
	}

	int b;
};

class C :public B
{
public:
	C()
	{
		cout << this << endl;
		cout << typeid(this).name() << endl;
	}

	void func()
	{
		cout << &a << endl;
		cout << &b << endl;
		cout << &c << endl;
	}

	int c;
};

int main()
{
	C c;
	cout << "&c " << &c << endl;
	cout << "*************" << endl;
	c.func();
	return 0;
}

运行结果:
运行结果
类A,B,C 和对象 c 地址相同。
类A,B,C 的类型不同,分别为 class A*, class B*, class C*
从结果得出:子类生成对象,先构造父类,后构造子类。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:13:21  更:2022-03-15 22:18:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:53:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码