c++(五)
- 继承
- 基类和派生类
- 继承的格式
- 继承的方式
- 三种:public、private、protected
- 继承的规则
- 多层继承
- 多重继承
- 类与类的关系
继承
- 一个新类从已有的类那里获得其已有特性(属性、行为),这种现象称为类的继承
基类和派生类
<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>在子类创建对象的时候,若没有指定父类要执行的构造函数,父类就会执行它的默认构造函数
多层继承
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的关系
登录类、注册类、
登录类中包含了编辑框类、按钮类、标签类的对象 ,这些标签、编辑框、按钮都是构成这些界面的组件!