c++(五)

继承

  • 一个新类从已有的类那里获得其已有特性(属性、行为),这种现象称为类的继承

基类和派生类

<1>从已有的类(父类/基类)产生一个新的子类,称为类的派生。
<2>派生类是基类的具体化,而基类则是派生类的抽象。

  • 当新的类是已经存在的类的一种特殊版本的时候,可以使用继承
  • 子类要继承父类的所有特性(属性和行为),但是构造函数、析构函数是不能被继承的,友元也不能被继承,因为它不是类的成员

继承的格式

class 类名: 访问限定符 基类名
{
;
}

继承的方式

三种:public、private、protected

三种:public、private、protected

<1>以public的方式继承
在这里插入图片描述
<2>以private方式继承
在这里插入图片描述
<3>以protected方式继承
在这里插入图片描述

总结:
<1>不管使用哪种方式继承,父类的private成员在子类内部外部都不可访问
<2>不管使用哪种方式继承,父类的protected成员在子类内部可以访问,子类外部不可访问
<3>只有采用public方式继承的时候,父类中是什么样子的访问限定符在子类中也是什么样的访问限定符
<4>在继承时,父类中的成员变量一般建议放在protected中
<5>继承的方式建议用public的方式去继承

子类构造函数的执行
在继承关系中,创建子类对象时,先执行父类的构造函数,再执行子类的构造函数
子类析构函数的执行
在继承关系中,当子类的生命周期结束的时候,先执行子类的析构函数,再执行父类的析构函数

继承的规则

<1>子类的构造函数只会对子类的对象进行空间的分配和初始化,父类中继承来的属性只能由父类的构造函数
进行初始化
<2>在子类创建对象的时候,若没有指定父类要执行的构造函数,父类就会执行它的默认构造函数

在这里插入图片描述

重定义

重定义(隐藏)的概念: 在继承关系中,子类有和父类同名的函数!!!
重载: 在同一个作用域内,函数功能相似,函数名相同,参数不同与返回值类型无关的一组函数被称为函数重载!
重定义:父类的方法不能满足子类的需求了,就可以重定义父类中的方法了
在这里插入图片描述
在类继承中,重定义,重载。
重定义函数名相同,返回类型必须相同,参数列表可以相同,可以不同;只要子类出现与父类同名的函数,子类就不会继承父类同名函数(隐藏)。
重载,函数名相同,返回类型和参数列表至少一个不同。
当该同名函数在父类声明为虚函数时(virtual),称为重写(覆盖),且需保证子类中的函数首部与父类中函数的首部是一模一样的,首部指的是:函数类型 函数名(参数列表)。

多层继承

A–>B–>C

如果不指定父类的构造函数,默认执行的是父类的默认构造函数

#include <iostream>
using namespace std;
/*
* 多重继承
*/
class People
{
public:
	People()
	{
		cout << "父类默认构造" << endl;
	}
	People(string name , int age = 18):name(name),age(age)
	{
		cout << "父类构造" << endl;
	}
	~People()
	{
		cout << "父类析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ","
			<< "年龄:" << this->age << endl;
	}
private:
protected:
	string name;
	int age;
};
class Stu : public People
{
public:
	Stu(int sno = 1, string name = "李四", int age = 18) :sno(sno)
	{
		cout << "子类构造函数" << endl;
	}
	~Stu()
	{
		cout << "子类析构" << endl;
	}
	//重定义
	void show()
	{
		cout << "学号:" << this->sno << ",姓名:" << this->name << ",年龄:" << this->age << endl;
	}
private:
protected:
	int sno;
};

int main()
{
	Stu stu1;
	stu1.show();
	return 0;
}

在这里插入图片描述
指定执行父类的构造函数

#include <iostream>
using namespace std;
/*
* 多重继承
*/
class People
{
public:
	People()
	{
		cout << "父类默认构造" << endl;
	}
	People(string name , int age = 18):name(name),age(age)
	{
		cout << "父类构造" << endl;
	}
	~People()
	{
		cout << "父类析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ","
			<< "年龄:" << this->age << endl;
	}
private:
protected:
	string name;
	int age;
};
class Stu : public People
{
public:
	Stu(int sno = 1, string name = "李四", int age = 18) :People(name, age),sno(sno)
	{
		cout << "子类构造函数" << endl;
	}
	~Stu()
	{
		cout << "子类析构" << endl;
	}
	//重定义
	void show()
	{
		cout << "学号:" << this->sno << ",姓名:" << this->name << ",年龄:" << this->age << endl;
	}
private:
protected:
	int sno;
};

int main()
{
	Stu stu1;
	stu1.show();

	Stu stu2(2, "王五", 22);
	stu2.People::show();
	stu2.show();

	return 0;
}

在这里插入图片描述

多重继承

在这里插入图片描述
**注意:**在多重继承关系中,先执行谁的构造函数与初始化的顺序无关,是由继承的先后顺序决定的
在这里插入图片描述
出现的问题:
在这里插入图片描述
解决:
<1>加上作用域(不合适)
在这里插入图片描述
<2>虚继承
在这里插入图片描述

#include <iostream>
using namespace std;
/*
* 多重继承
*/
class People
{
public:
	People()
	{
		cout << "people 默认构造" << endl;
	}
	People(string name, int age = 20) :name(name), age(age)
	{
		cout << "people类构造" << endl;
	}
	~People()
	{
		cout << "people 析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ",年龄:" << this->age << endl;
	}
private:
protected:
	string name;
	int age;
};
class Worker :virtual public People
{
public:
	Worker(string name, int age, int salary = 30000) :People(name, age), salary(salary)
	{
		cout << "worker构造" << endl;
	}
	~Worker()
	{
		cout << "worker析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ",年龄:" << this->age << ",薪资:" << this->salary << endl;
	}
private:
protected:
	int salary;
};
class Farmer : virtual public People
{
public:
	Farmer(string name, int age, int filecout = 200) :People(name, age), filecout(filecout)
	{
		cout << "farmer构造" << endl;
	}
	~Farmer()
	{
		cout << "farmer析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ",年龄:" << this->age << ",几亩田:" << this->filecout << endl;
	}
private:
protected:
	int filecout;
};
class workFarmer : public Worker, public Farmer
{
public:
	workFarmer(string name = "溜溜", int age = 22, int salary = 29830, int filecout = 200,int car = 3) :
		Worker(name, age, salary), Farmer(name, age, filecout),People(name,age),car(car)
	{
		cout << "workFarmer构造" << endl;
	}
	~workFarmer()
	{
		cout << "workFarmer析构" << endl;
	}
	void show()
	{
		cout << "姓名:" << this->name << ",年龄:" << this->age << ",几亩田:" << this->filecout 
			<<",薪资:" << this->salary << ",车辆:" << this->car << endl;
	}
private:
protected:
	int car;
};

int main()
{
	workFarmer wf1;
	wf1.show();
	wf1.Farmer::show();
	wf1.Worker::show();
	return 0;
}

在这里插入图片描述

类与类的关系

继承关系 is a的关系
编辑框类、按钮类、标签类 都称为组件类
编辑框、按钮、标签都是组件中的一种。
包含关系 has a的关系
登录类、注册类、
登录类中包含了编辑框类、按钮类、标签类的对象 ,这些标签、编辑框、按钮都是构成这些界面的组件!

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值