继承#1
如果一个类属于另一个类的范畴,也就是说另一个类包含这个类。为了方便,只需要定义已有类中没有的成员就可以建立一个新类,而继承正是为了方便该操作的进行。
在一个类层次中,最顶部的类被称为基类,通过基类所派生出的即为子类,子类的上一级就是它的父类。
如何继承
我们在这里简单介绍继承的方法,现有一学生类,但现在我们需要增加一个硕士研究生类,显然,硕士是属于学生这个基类的,所以我们用继承的方法来创建研究生类,参考以下程序片段
class student{
public:
//..
private:
//..
};
class graduateStudent:public student{//以public的继承类型继承student类
//..
};
在类名后面跟上 :继承类型 要继承的父类
即可,关于继承类型,将在后面的内容详细说明。
完成继承之后,graduateStudent 类将继承 student 类中的成员,graduateStudent 类中会多出在声明研究生类时所新增的成员,研究生类对象的尺寸即为研究生类中增加的部分 + 学生类中的部分。
派生类的构造
上面的内容说明了如何继承父类从而派生出新的类,但派生类中含有父类的成员,如何对其进行构造?构造函数应该怎么写呢?
默认情况下派生类对象创建时,会调用默认构造函数,而派生类的默认构造函数又会先调用基类的默认构造函数,从而完成派生类对象的初始化。
派生类的成员函数可以访问基类的公共及保护数据成员,甚至可以直接初始化它们,但更好的习惯是,通过基类的接口去操作基类的数据成员,类与类之间尽量互不干扰,使用接口进行沟通,方便后续维护。
具体操作如以下程序片段
class graduateStudent :public student{
public:
graduateStudent(string nName)
:student(nName)//使用student类的构造函数对student类中的数据成员进行初始化,多个用逗号隔开
{
qualifierGrade = 0;
}
//..
};
以上代码片段可以发现,student 基类初始化由 student(string nName)完成,派生类 graduateStudent 的初始化也总是由基类的初始化开始,即使顺序不同,也会先调用基类的构造函数。
继承方式(引出 protected 与 private 的区别)
在我刚讲面向对象编程时,就提到的类的三种访问权限:
- public
- protected
- private
在之前,后两者没有任何区别,它们的区别也只有在继承中会体现出来,可以说 protected 是专门为继承而设计的。以下片段演示了三种继承方式
class basic{
//..
};
class pub:public basic{//公共继承
//..
};
class pro:protected basic{//保护继承
//..
};
class pri:private basic{//私有继承
//..
};
- 公共继承:继承父类的一切,但基类的 private 成员不能访问,将基类的保护成员和公有成员视为自己的保护和公有成员。
- 保护继承:将基类的保护和公有成员全部视为自己的保护成员。
- 私有继承:将基类的保护和公有成员全部视为自己的私有成员。
基类成员在派生类中的访问控制属性*
基类访问属性 | public | protected | private |
---|---|---|---|
公共继承 public | public | protected | 隔离 |
保护继承 protected | protected | protected | 隔离 |
私有继承 private | private | private | 隔离 |
公共继承(公有继承)意味着外界可以访问基类中的 public 成员,仅不能访问 protected 成员;
保护继承意味着外界不能访问基类中的任何成员,但可以通过派生类中的自身公有成员函数访问继承出的保护成员;
私有继承同样也意味着外界不能访问基类中的任何成员,但可以通过派生类中的自身公有成员函数访问继承出的私有成员。
保护继承与私有继承类似,私有继承会影响下一次的继承,因为 private 成员是不能被派生类访问的。
调整访问控制
在派生类中,可以调整成员的访问控制属性,将公有调整为私有,保护调整为公有等等操作。
class basic{
int a1;
protected:
int a2;
public:
//..
};
class pri:private basic{//私有继承,使basic中的public和protected均以private方式继承
public:
using basic::a2;//抽取其中可见的成员a2为公有,原本继承为private
};
int main(){
pri p;
p.a2=1;//ok 公有成员
return 0;
}
调整的前提是在派生类中该成员可见,如果是基类中的 private 成员(在派生类中不可见)那么将不能进行访问控制权限的调整。
编辑:Henry 2021-03-06 未授权禁止转载
版权属于:字节星球/肥柴之家 (转载请联系作者授权)
原文链接:https://www.bytecho.net/archives/1716.html
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。