MENU

继承#1

• March 6, 2021 • Read: 1824 • 学习笔记,C++

继承#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 的区别)

在我刚讲面向对象编程时,就提到的类的三种访问权限:

  1. public
  2. protected
  3. private

在之前,后两者没有任何区别,它们的区别也只有在继承中会体现出来,可以说 protected 是专门为继承而设计的。以下片段演示了三种继承方式

class basic{
    //..
};
class pub:public basic{//公共继承
    //..
};
class pro:protected basic{//保护继承
    //..
};
class pri:private basic{//私有继承
    //..
};
  • 公共继承:继承父类的一切,但基类的 private 成员不能访问,将基类的保护成员和公有成员视为自己的保护和公有成员。
  • 保护继承:将基类的保护和公有成员全部视为自己的保护成员。
  • 私有继承:将基类的保护和公有成员全部视为自己的私有成员。
基类成员在派生类中的访问控制属性*
基类访问属性publicprotectedprivate
公共继承 publicpublicprotected隔离
保护继承 protectedprotectedprotected隔离
私有继承 privateprivateprivate隔离

公共继承(公有继承)意味着外界可以访问基类中的 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 国际许可协议进行许可。

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment