类继承
(1)当创建一个类时,不需要重新编写新的成员变量和成员函数,只需要新建的类继承了一个已有的类的成员。已有的类称为基类或父类,新建的类称为派生类或子类。
(2)一个类可以有多个父类,继承多个父类的特性。
(3)继承可以实现面向对象代码重用,继承也时实现多态的必要语法。
(4)继承默认的访问权限时私有的
class 子类名 : 继承权限 父类名, 继承权限 父类名...
{};
继承中构造函数的赋值方法:子类通过参数列表赋值
如果没有显式的调用父类构造函数,会默认调用父类无参的构造函数
#include <iostream>
using namespace std;
//1.当父类没有显示的定义构造,那么会调用父类默认的构造函数
//2.父类显示的定义了构造,那么会调用父类显示的无参的构造
//3.先创建父类,后创建子类
class Food
{
public:string chips;Food(string chips):chips(chips){cout<<"food create"<<endl;}
};
//添加继承关系:冒号: 继承权限 父类
//kfc:子类 派生类 Food:基类 父类
class KFC : public Food
{string chips;
public://子类的初始化列表中,初始化父类的构造函数KFC(string chips):Food(“aaaa”) ,chips(chips)//匿名对象{// this->chips = chips;cout<<"kfc create"<<endl;}void show(){cout<<"kfc: "<<chips<<endl;}
};
int main()
{KFC kfc("薯条");kfc.show();return 0;
}
子类的初始化列表中可以通过父类的构造函数来初始化父类的成员
如果父类中没有无参构造函数,子类的初始化列表中必须显式的调用父类带参的构造函数
#include <iostream>
using namespace std;//1.当父类没有显示的定义构造,那么会调用父类默认的构造函数
//2.父类显示的定义了构造,那么会调用父类显示的无参的构造
//3.先创建父类,后创建子类
class Food
{
public:string chips;Food(string chips):chips(chips){cout<<"food create"<<endl;}
};//添加继承关系:冒号: 继承权限 父类
//kfc:子类 派生类 Food:基类 父类
class KFC : public Food
{public://子类的初始化列表中,初始化父类的构造函数KFC(string chips):Food(chips) //匿名对象{// this->chips = chips;cout<<"kfc create"<<endl;}void show(){cout<<"kfc: "<<chips<<endl;}
};
int main()
{KFC kfc("薯条");kfc.show();return 0;
}
继承访问权限的影响
(1)public继承 子类继承后的访问权限不变
(2)protected继承 子类继承后,父类中的public变成protected,其它不变(protected:只有子类可以用),类外不可用
(2)private继承 子类继承后,父类中的public和protected变成private,其他不变
继承时的重定义(遮蔽问题)
如果派生类中的成员(包括成员变量和成员函数)和基类中的成员重名,那么就会遮蔽从基类继承过来的成员。所谓遮蔽,就是在派生类中使用该成员(包括在定义派生类时使用,也包括通过派生类对象访问该成员)时,实际上使用的是派生类新增的成员,而不是从基类继承来的。
基类成员函数和派生类成员函数不构成重载
基类成员函数和派生类成员函数不会构成重载,如果派生类有同名函数,那么就会遮蔽基类中的所有同名函数,不管它们的参数是否一样。
虚函数(virtual)
重写 overload(重点)
子类中定义和父类中虚函数同名,同返回值类型,同参数列表的函数
重载、重写、重定义的区别