继承与派生【C++】
1、基本概念
在 C++ 中可重用性是通过继承这一机制来实现的。因此,继承是 C++ 的一个重要组成部分。在 C++ 中,继承就是在一个已存在的类的基础上建立一个新的类。已存在的类称为 “基类” 或 “父类”。新建立的类称为 “派生类” 或 “子类”。
一个新类从已有的类那里获得其已有特性,这种现象称为类的继承。通过继承,一个新建子类从已有的父类那里获得父类的特性。从另一角度说,从已有的类(父类)产生一个新的子类,称为类的派生。
类的继承是用已有的类来建立专用类的编程技术。派生类继承了基类的所有数据成员和成员函数,并可以对成员作必要的增加或调整。一个基类可以派生出多个派生类,每一个派生类又可以作为基类再派生出新的派生类,因此基类和派生类是相对而言的。
一个派生类只从一个基类派生,这称为单继承,这种继承关系所形成的层次是一个树形结构。一个派生类有两个或多个基类的称为多重继承。而基类和派生类的关系,可以表示为:派生类是基类的具体化,而基类则是派生类的抽象。
2、派生类的声明方式
声明派生类的一般形式为:
class 派生类名:[ 继承方式 ] 基类名 {
派生类新增加的成员
};
继承方式是可选的,具体包括:public(公用的)、private(私有的)、protected(受保护的)。若不写,则默认为 private(私有的)。
3、派生类的构成
派生类中的成员包括从基类继承过来的成员和自己增加的成员两大部分。如下图所示:
在基类中包括数据成员和成员函数两部分,派生类分为两大部分:一部分是从基类中继承来的成员,另一部分是在声明派生类时增加的部分。每一部分均分别包括数据成员和成员函数。
实际上,并不是把基类的成员和派生类自己增加的成员简单地加在一起就成为派生类。构造一个派生类包括以下三部分工作:
(1)从基类接收成员。派生类把基类全部的成员(不包括构造所数和析构函数)接收过来,也就是说是没有选择的,不能选择接收其中一部分成员,而舍弃另一部分成员。从定义派生类的一般形式中可以看出是不可选择的。
(2)调整从基类接收的成员。接收基类成员是程序人员不能选择的,但是程序人员可以对这些成员作某些调整。例如可以改变基类成员在派生类中的访问属性,这是通过指定继承方式来实现的。如可以通过继承把基类的公用成员指定为在派生类中的访问属性为私有(在派生类外不能访问)。此外,可以在派生类中声明一个与基类成员同名的成员,则派生类中的新成员会覆盖基类的同名成员,但应注意:如果是成员函数,不仅应使函数名相同,而且函数的参数表(参数的个数和类型)也应相同,如果不相同,就成为函数的重载而不是覆盖了。用这样的方法可以用新成员取代基类的成员。
(3)声明派生类时新增加的成员。要根据需要仔细考虑应该增加哪些成员,精心设计。此外,还需要自己定义派生类的构造函数和析构函数,因为构造函数和析构函数是不能从基类继承的。
4、派生类成员的访问属性
如何确定基类的成员在派生类中的访问属性的问题,不仅要考虑到基类成员所声明的访问属性,而且还要考虑派生类所声明的对基类的继承方式,根据这两个因素共同决定基类成员在派生类中的访问属性。
在派生类中,对基类的继承方式有 public(公用的)、private(私有的)、protected(受保护的)这三种。不同的继承方式决定了基类成员在派生类中的访问属性。简单的说:
(1)公用继承
基类的公用成员和保护成员在派生类中保持原有访问属性,而私有成员仍基类私有。
(2)私有继承
基类的公用成员和保护成员在派生类中成了私有成员,而私有成员仍基类私有。
(3)受保护的继承
基类的公用成员和保护成员在派生类中成了保护成员,而私有成员仍基类私有。
(4.1)公用继承
在定义一个派生类的时候将基类的继承方式指定为 public 的,称为公用继承。公有基类的成员在派生类中的访问属性如下表:
公用基类的成员 |
在派生类中的访问属性 |
私有成员 |
不可访问 |
公用成员 |
公用 |
保护成员 |
保护 |
【例】访问公有基类的成员
#include <iostream> #include <cstring> using namespace std; class Student { public: void get_value() { cin >> num >> name >> sex; } void display() { cout << "num:" << num << endl; cout << "name:" << name << endl; cout << "sex:" << sex << endl; } private: int num; string name; char sex; }; class Student1 :public Student { // 以 public 方式声明派生类 Student1 public: void get_value() { Student::get_value(); // 调用基类的公用成员函数 cin >> age >> addr; } void display() { //cout << "num:" << num << endl; // 错误,不能引用基类的私有成员 //cout << "name:" << name << endl; // 错误,不能引用基类的私有成员 //cout << "sex:" << sex << endl; // 错误,不能引用基类的私有成员 Student::display(); // 调用基类的公用成员函数 cout << "age:" << age << endl; cout << "address:" << addr << endl; } private: int age; string addr; }; int main() { Student1 stud; stud.get_value(); stud.display(); return 0; }
(4.2)私有继承
在定义一个派生类的时候将基类的继承方式指定为 private 的,称为私有继承。私有基类的成员在派生类中的访问属性如下表:
私有基类的成员 |
在派生类中的访问属性 |
私有成员 < |