继承
- 一个新类从已有的类那里获得其已有特性(属性、行为),这种现象称为类的继承
基类和派生类
<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的关系
登录类、注册类、
登录类中包含了编辑框类、按钮类、标签类的对象 ,这些标签、编辑框、按钮都是构成这些界面的组件!