19. 多态

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

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

1. 多态分成两类:

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

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

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

3. 动态多态满足关系

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

4. 动态多态的使用

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

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

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

#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;
}
上一篇:Mysql—用存储过程和事件每月定时创建一张数据库表


下一篇:Scala 前置、中置、后置操作符