zoukankan      html  css  js  c++  java
  • 19. 多态

    多态是 C++ 面向对象三大特性之一,思考我们为什么要学习多态?

    • 在C++中,多态的实现是通过覆盖(override),而决定是否覆盖函数的关键点在于该基类中的函数是否有关键字 virtual,此函数被称为虚函数。
    • 多态的优点
      • 代码组织结构清晰
      • 可读性强
      • 利于前期和后期的扩展以及维护

    1. 多态分成两类:

    • 静态多态:函数重载和运算符重载属于静态多态,复用函数名
    • 动态多态:派生类和虚函数实现运行时多态

    2. 静态多态和动态多态的区别:

    • 静态多态的函数地址早绑定、编译阶段确定函数地址
    • 动态多套的函数地址晚绑定、运行阶段确定函数地址

    3. 动态多态满足关系

    • 有继承关系
    • 子类重写父类中的虚函数(函数返回值类型相同,函数名相同,参数列表相同称为重写)

    4. 动态多态的使用

    • 父类的指针或引用,执行子类对象

    你可以理解为:虚函数最大的用途就是能让父类指向子类

    通过案例来了解静态多态和静态多态

    #include <iostream>
    using namespace std;
    //多态
    //动物类
    class Animal
    {
    public:
          virtual void speak() //虚函数,字节为 4,指针的大小始终为 4 
          {
                cout << "动物在说话" << endl;
          }
    };
    class Cat
    {
    public:
          void speak()
          {
                cout << "猫在说话" << endl;
          }
    };
    
    //执行说话的函数
    //地址早绑定,在编译的阶段确定了函数地址
    //如果执行让猫说话,那么地址不得提前绑定,也就是晚绑定(在Animal前加上关键字 virtual)
    void dospeak(Animal &animal) //引用方式;  Animal &animal = cat;
    {
          animal.speak();
    }
    void test01()
    {
          Cat cat;
          dospeak(cat);
    }
    int main()
    {
          test01();
          system("pause");
          return 0;
    }
    

    多态小案例 —— 计算器

    案例描述:分别用普通写法多态技术,设计实现两个操作数进行运算的计算器类

    //普通实现
    #include <iostream>
    using namespace std;
    #include <string>
    
    class Calculator
    {
    public:
          int getresult(string oper)
          {
                if(oper == "+")
                {
                      return m_num1+m_num2;
                }
                else if(oper =="-")
                {
                      return m_num1-m_num2;
                }
                else if(oper =="*")
                {
                      return m_num1*m_num2;
                }
          // 如果要扩展新功能,需要修改源码,在真实开发中题常开闭原则
          // 开闭原则:对扩展进行开放,对修改进行关闭
          }
          int m_num1; //操作数 1
          int m_num2; //操作数 2
    };
    void test01()
    {
          Calculator c;
          c.m_num1 = 10;
          c.m_num2 = 5;
          cout << c.m_num1 << "+" << c.m_num2 << " = " << c.getresult("+") << endl;
          cout << c.m_num1 << "-" << c.m_num2 << " = " << c.getresult("-") << endl;
          cout << c.m_num1 << "*" << c.m_num2 << " = " << c.getresult("*") << endl;
    }
    
    //利用多态
    //实现计算器的抽象类
    class abstractcalculator
    {
    public:
          virtual int getresult()
          {
                return 0;
          }
          int m_num1;
          int m_num2
    };
    class addcalculator : public abstractcalculator  //加法计算器
    {
    public:
          int getresult()
          {
                return m_num1+m_num2;
          }
    };
    class subcalculator : public abstractcalculator  //减法计算器
    {
    public:
          int getresult()
          {
                return m_num1-m_num2;
          }
    };
    class mulcalculator : public abstractcalculator  //加法计算器
    {
    public:
          int getresult()
          {
                return m_num1*m_num2;
          }
    };
    void test02()
    {
          // 多态使用条件:父类指针或引用指向子类对象
          abstractcalculator *abc=new addcalculator;  //开辟在堆区,记得手动释放
          abc -> m_num1 = 20;
          abc -> m_num2 =40;
          cout << abc->m_num1 << "+" << abc -> m_num2 >> "=" >> abc->getresult() << endl;
          //用完记得销毁
          delete abc;
    }
    int main()
    {
          test01();
          test02();
          system("pause");
          return 0;
    }
    
  • 相关阅读:
    用Python获取Linux资源信息的三种方法
    对python中元类的理解
    一道有趣的和编程无关的编程题思考
    Python编程进阶
    函数计算的 Python手册小问题
    Linux 命令
    pyechart
    KV数据库Redis
    微博API 学习记录
    非阻塞式的 requests.post 学习
  • 原文地址:https://www.cnblogs.com/BY1314/p/13111887.html
Copyright © 2011-2022 走看看