C++(6) 继承

继承

1. 继承
1.1 什么是继承

面向对象程序设计中最重要的一个概念是继承。继承允许我们依据另一个类来定义一个类,这使得创建和维护一个应用程序变得容易。达到重写代码功能和提高执行效率的效果。

当创建一个类时,不需要重新编写新的数据成员和成员函数, 只需要指定新键的类继承了一个已有的类的成员即可。这个已有的类称为基类,新建的类称为派生类

1.2 C++ 继承方式
1.2.1 基本案例

格式

class 子类 : 权限修饰符
{
}
#include <iostream>

using namespace std;

class Base
{
public:
    int mA = 1;
protected:
    int mB = 2;
private:
    int mC = 3;
};

/*
Base 类是 Son 的一个 public 修饰父类
Son 类是 Base 类的一个子类,或者可以认为 Son 类是 Base 类 派生类
*/
class Son : public Base
{
public:
    int nA = 1;
protected:
    int nB = 2;
private:
    int nC = 3;
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;

    cout << "mA : " << s->mA << endl;
    // 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
    // 子类对象无法在类外调用 mB
    // cout << "mB : " << s->mB << endl;
    // 当情况下,mB 是 Base 类中的 protected 修饰 成员变量,同时使用 public 方式继承
    // 子类对象无法s使用mC
    // cout << "mC : " << s->mC << endl;

    cout << "nA : " << s->nA << endl;

    // cout << "nB : " << s->nB << endl;

    // cout << "nC : " << s->nC << endl;

    return 0;
}
1.2.2 继承权限组合
继承对应的权限修饰\原修饰符 public protected private
public public protected 无法继承
protected protected protected 无法继承
private private private 无法继承
#include <iostream>

using namespace std;

/*
public:
    类内、子类类外都可以使用
protected:
    类内、子类可以使用,类外无法使用
private:
    类内可以使用,子类、类外无法使用
*/
class Base
{
public:
    int mA = 1;
    void test1() { cout << "test1 funtion" << endl; }
protected:
    int mB = 1;
    void test2() { cout << "test2 funtion" << endl; }
private:
    int mC = 1;
    void test3() { cout << "test3 funtion" << endl; }
};

/*
public 继承方式,父类的成员权限修饰符变化
    public --> public
    protected --> protected
    private 无法继承
*/
class Son1: public Base
{
public:
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;

        test1();
        test2();
        // test3();
    }
};

/*
protected 继承方式,父类的成员权限修饰符变化
    public --> protected
    protected --> protected
    private 无法继承
*/
class Son2: protected Base
{
public:
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;

        test1();
        test2();
        // test3();
    }
};

/*
private 继承方式,父类的成员权限修饰符变化
    public --> private
    protected --> private
    private 无法继承
*/
class Son3: private Base
{
    void test()
    {
        cout << mA << endl;
        cout << mB << endl;
        // cout << mC << endl;
    }
};


int main(int argc, char const *argv[])
{
    Son1 *s1 = new Son1;
    cout << s1->mA << endl;

    Son2 *s2 = new Son2;
    // cout << s2->mA << endl;

    Son3 *s3 = new Son3;
    // cout << s3->mA << endl;
    
    return 0;
}
1.2.3 继承中构造函数的说法
#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;
    }
};

class GrandSon : public Son
{
public:
    GrandSon()
    {
        cout << "GrandSon 类析构函数" << endl;
    }
    ~GrandSon()
    {
        cout << "GrandSon 类析构函数" << endl;
    }
};

int main(int argc, char const *argv[])
{
    // 显式调用的时子类的五承诺书构造函数
    Son *s1 = new Son();
    /*
    Base 类构造函数
    Son 类构造函数
    */
    cout << "----------------------------------" << endl;
    delete s1;
    /*
    Son 类析构函数
    Base 类析构函数
    */
    cout << "----------------------------------" << endl;

    GrandSon *s2 = new GrandSon();
    /*
    Base 类构造函数
    Son 类构造函数
    GrandSon 类构造函数
    */
    cout << "----------------------------------" << endl;

    delete s2;
    /*
    GranSon 类析构函数
    Son 类析构函数
    Base 类析构函数
    */

    return 0;
}
1.2.4 继承中析构函数的执行顺序

在这里插入图片描述

1.2.5 继承中变量名称冲突问题
class Base
{
public:
    int num;
};

class Son : public Base
{
public:
    int num;
    
    void test()
    {
        // int Son::num;
        /*
        如果直接使用,编译器会考虑按照就近原则方式进行数据分配
        首选是 Son 类中的 num 数据
        */
        cout << num << endl;
        // int Base::num;
        /*
        如果需要使用 Base 中的 num,需要利用 :: 作用域运算符
        限制当前变量的作用范围
        */
        cout << Base::num << endl;
    }
};
1.2.6 继承中函数【重写】
#include <iostream>

using namespace std;

class Father
{
public:
    void name() { cout << "小鱼丸" << endl; }
    void hobby() { cout << "唱歌" << endl; }
};

/*
函数的重写 Ovreride
    1. 存在必要的继承关系
    2. 要求子类重写父类的函数,函数声明必须一致
    3. 可以按照子类要求完成哈桑农户内容实现

重写的存在可以降低开发中函数命名压力
*/
class Son : public Father
{
public:
    void name() { cout << "Glade" << endl; }
    void hobby() { cout << "吃" << endl; }
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;  

    /*
    子类可以通过 public 继承得到父类中 public 修饰函数,
    类内调用但是父类的函数有可能无法满足子类的特征需求

    【重写父类函数】 Override
    */
    s->name();
    s->hobby();

    return 0;
}
{
public:
    void name() { cout << "Glade" << endl; }
    void hobby() { cout << "吃" << endl; }
};

int main(int argc, char const *argv[])
{
    Son * s = new Son;  

    /*
    子类可以通过 public 继承得到父类中 public 修饰函数,
    类内调用但是父类的函数有可能无法满足子类的特征需求

    【重写父类函数】 Override
    */
    s->name();
    s->hobby();

    return 0;
}

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-30 12:44:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-30 12:44:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-30 12:44:01       87 阅读
  4. Python语言-面向对象

    2024-01-30 12:44:01       96 阅读

热门阅读

  1. Redis:企业级的深入

    2024-01-30 12:44:01       43 阅读
  2. C语言数据结构——单链表

    2024-01-30 12:44:01       73 阅读
  3. Redis -- 背景知识

    2024-01-30 12:44:01       62 阅读
  4. 【C++】构造函数

    2024-01-30 12:44:01       55 阅读
  5. 如何系统地自学 Python?

    2024-01-30 12:44:01       74 阅读
  6. 【Vue3】状态管理工具——pinia的使用

    2024-01-30 12:44:01       71 阅读