C++中类之间的关系,一共分为以下三种:
- has-a:包含关系。表示类A的一个成员是类B,举例来说,比如类
Student
中,有数据成员score
,而score
是属于类Score
的; - use-a:使用关系。表示类B会用到类A的成员,比如类
State
会用到类Region
中的成员函数getArea()
,我们可以通过定义友元类来实现快捷编程; - is-a:继承关系。表示类B是类A的一个子集,比如类
Student
是类Person
的一个子集,我们就说类Student
继承了类Person
;
本文,我要说的就是is-a这种关系。也叫继承
继承的概念
如果类B
是继承于类A
的,我们就把类A
叫做“基类”(也叫父类),而把类B
叫做“派生类”(也叫“子类”)。一个子类继承了它的父类所有可访问的数据成员和函数,这样,我们在编程时,不需要“白手起家”了,即不需要重头开始定义一个已经定义了的类的子类,大大节省了开发时间。
继承的特点有如下4条:
- 子类拥有父类所有课访问的数据和方法(除了构造函数和析构函数);
- 子类可以拥有父类没有的属性和方法;
- 子类是本质上也是一种特殊的父类;
- 子类对象可以当做父类对象使用;
其实关于继承的理解,只需要把握一点:子类是父类的特例,父类有的特性,子类都应该有。
三种继承的方式
C++中,定义子类的语法形式如下:
class DeriveClassName : access-lable BaseClassName
其中,access-lable
为继承的方式,一共有三种:
公有继承(public):子类继承了父类的公有成员和保护成员,并作为公有成员。而父类的私有成员仍然是私有的,不能被子类访问。
私有继承(private):子类继承了父类的公有成员和保护成员,并作为私有成员。而父类的私有成员仍然是私有的,不能被子类访问。
保护继承(protected):子类继承了父类的公有成员和保护成员,并作为保护成员。而父类的私有成员仍然是私有的,不能被子类访问。
这里公有成员和私有成员就不解释了,稍微说一下保护成员:保护成员用关键字protected
定义,它的访问权限介于public
和private
之间,它可以被类内访问,也可以被友元类或者子类访问。
举个公有方式继承的例子:
// Person类是基类
class Person {
public:
...
Private:
...
};
// Student类是派生类,按公有方式继承
class Student:public Person {
public:
...
Private:
...
};
从上面说的3种继承方式可以看出,基类的私有成员都不能被派生类访问,此外,3种继承方式的差别在于对于基类的公有成员和保护成员在派生类中的访问模式不同(公有、私有或者保护)。
构造函数和析构函数
调用构造函数
上面说了,不能继承基类的构造函数和析构函数。但是有些时候,我们是需要在派生类中调用基类的构造函数或者析构函数的。具体的例子可以参照我下面写的代码。基类Person
的拥有构造函数:Person(string id, string name)