前言
c++面向对象三大特性:封装,继承,多态。通过本文我们将了解什么是类的继承以及继承的使用。
Q:什么是继承?
A: 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。子类的对象拥有其父类全部属性与服务,称作子类对父类的继承。例如,轮船、客轮;人、大人。一个类可以是多个父类的子类,它从多个父类中继承了属性与服务,这称为多继承。例如,客轮与轮船和客运工具。
一、类的继承
在学习继承之前,我们先来了解一下基类和派生类。
1、基类与派生类
我们先来看下面这串代码:
#include<iostream> using namespace std; class Student { public: int age; char *name; Student() { age = 18; name = "Ceylan"; } }; class Undergraduate:public Student { public: int grate; Undergraduate():Student() { grate = 1; } }; int main() { Undergraduate s; cout << s.age << endl; return 0; }
在这个例子中,学生类Student就可以作为一个基类,研究生类Undergraduate就是一个派生类。
在main函数中,我们首先用构造函数进行初始化,研究生类Undergraduate通过公共方法继承了Student类,也就是继承 了Student类的成员属性和方法,就可以输出Student的成员变量age的值。
2、什么是派生类
Q:什么是派生类?
A: 派生类就是继承了一个或者多个类的子类。
3、派生类如何定义
Q:派生类如何定义?
A: 参考上文代码,程序中先定义基类Student,再定义派生类Student继承基类Student。需要注意,在c++中,继承可以是多继承,也就是说派生类可以同时继承多个类,语法如下所示:
class Derived:public Base1,public Base2 { //... }
4、派生类的特点
- 派生类拥有基类的所有数据成员和成员函数(不包括构造函数和析构函数)
- 派生类可以拥有基类没有的数据成员和成员函数
- 派生类对象可以通过基类的公有函数访问基类的私有成员
- 派生类可以看成是一种特殊的基类,也就是说可以把派生对象当成基类对象使用。
二、派生类的访问权限与作用
在类名冒号之后, 跟着的关键字不同,派生类的访问权限会有不同。根据关键字,可以分为三种情况,公有派生、保护派生、私有派生。
1、公有派生
class 类名∶public 基类 { // … };
公有派生使用public关键字来继承,公有派生的所有基类成员在派生类中保持原有的访问级别。
#include<iostream> using namespace std; class A { public: void setx(int n) { x = n; } void showx () { cout << x << endl; } public: int x; } ; class B: private A { public: void setxy(int n, int m) { setx(n); y = m; } void showxy() { cout << x << " " << y << endl; } public: int y; }; int main() { B s; s.setxy(10,20); s.showxy(); }
2、保护派生
class 类名∶protected 基类 { // … };
保护派生使用protected关键字来继承,保护派生中public成员protected成员、protected成员不变、private 成员不变。
3、私有派生
class 类名∶private 基类 { // … };
私有派生使用private 关键字来继承,私有派生中所有基类成员在派生类中都变为private成员。
三、派生类的构造函数与析构函数
派生类构造函数和析构函数的执行顺序
派生类继承基类后,当创建派生类对象时,也会调用基类的构造函数。那么,是先进行基类的构造和析构还是先进行派生类的构造和析构呢?我们来看看下面的代码案例:
#include<iostream> using namespace std; class Base { //声明基类 public: Base() { cout << "Base 类的构造函数" << endl; } ~ Base() { cout << "Base 类的析构函数" << endl; } }; class Son : public Base { public: Son() { cout << "Son 类的构造函数" << endl; } ~ Son() { cout << "Son 类的析构函数" << endl; } }; int main() { Son s; return 0; }
执行效果:
通常情况下,当创建派生类对象时, 首先执行基类的构造函数, 随后再执行派生类的构造函数。当结束派生类对象时, 则先执行派生类的析构函数, 随后再执行基类的析构函数。
四、多继承
Q:什么是多继承?
A:多继承是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有基类的成员。
多继承可能会引发基类中有同名成员的出现,使用时需要加上作用域进行区分,详细代码如下:
#include<iostream> using namespace std; class A1 { public: A1() { a = 100; } public: int a; }; class A2 { public: A2() { a = 200; } public: int a; }; class A3 : public A1,public A2 { public: A3() { a = 300; } public: int a; }; int main() { A3 s; cout << s.A1::a << endl; cout << s.A2::a << endl; cout << s.A3::a << endl; return 0; }