36 多态的概念和意义

1 多态的概念

  • 面向对象中期望的行为

    • 根据实际的对象类型判断如何调用重写函数,而不是指针/引用的类型
    • 父类指针(引用)指向
      • 父类对象则调用父类中定义的函数
      • 子类对象则调用子类中定义的重写函数
  • 面向对象中的多态的概念

    • 根据实际的对象类型决定函数调用的具体目标
    • 同样的调用语句在实际运行时有多种不同的表现形态
  • C++ 语言直接支持多态的概念

    • 通过使用 virtual 关键字对多态进行支持
    • virtual 声明的函数被重写后具有多态特性
    • virtual 声明的函数叫做虚函数
  • 示例1:多态

    • Demo

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Parent
      {
      public:
          // virtual关键字修饰
          virtual void print()
          {
              cout << "I'm Parent." << endl;
          }
      };
      
      class Child : public Parent
      {
      public:
          void print()
          {
              cout << "I'm Child." << endl;
          }
      };
      
      void how_to_print(Parent* p)
      {
          p->print();     // 希望展现多态的行为
      }
      
      int main()
      {
          Parent p;
          Child c;
          
          how_to_print(&p);    // Expected to print: I'm Parent.
          how_to_print(&c);    // Expected to print: I'm Child.
          
          return 0;
      }
      
    • 编译运行

      I'm Parent.
      I'm Child.
      

2 多态的意义

  • 多态的意义

    • 在程序运行过程中展现出多态的特性
    • 函数重写必须多态实现,否则没有意义
    • 多态是面向对象组件化程序设计的基础特性
  • 静态联编和动态联编

    • 静态联编

      • 在程序的编译期间就能确定具体的函数调用,如函数重载
    • 动态联编

      • 在程序实际运行后才能确定具体的函数调用,如函数重写
  • 示例2:动态联编和静态联编

    • Demo

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Parent
      {
      public:
          virtual void func()
          {
              cout << "void func()" << endl;
          }
          
          virtual void func(int i)
          {
              cout << "void func(int i) : " << i << endl;
          }
          
          virtual void func(int i, int j)
          {
              cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
          }
      };
      
      class Child : public Parent
      {
      public:
          //重写,构成多态
          void func(int i, int j)
          {
              cout << "void func(int i, int j) : " << i + j << endl;
          }
          
          //与父类的发生同名覆盖,与子类的发生重载
          void func(int i, int j, int k)
          {
              cout << "void func(int i, int j, int k) : " << i + j + k << endl;
          }
      };
      
      void run(Parent* p)
      {
          p->func(1, 2);     // 展现多态的特性
                             // 动态联编
      }
      
      
      int main()
      {
          Parent p;
          
          p.func();         // 静态联编
          p.func(1);        // 静态联编
          p.func(1, 2);     // 静态联编
          
          cout << endl;
          
          Child c;
          
          c.func(1, 2);     // 静态联编
          
          cout << endl;
          
          run(&p);
          run(&c);
          
          return 0;
      }
      
    • 编译运行

      void func()
      void func(int i) : 1
      void func(int i, int j) : (1,2)
      
      void func(int i, int j) : 3
      
      void func(int i, int j) : (1,2)
      void func(int i, int j) : 3
      
  • 示例3:多态应用

    • Demo:Boss VS Master => Boss VS NewMaster

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Boss
      {
      public:
          int fight()
          {
              int ret = 10;
              
              cout << "Boss::fight() : " << ret << endl;
              
              return ret;
          }
      };
      
      class Master
      {
      public:
          virtual int eightSwordKill()
          {
              int ret = 8;
              
              cout << "Master::eightSwordKill() : " << ret << endl;
              
              return ret;
          }
      };
      
      class NewMaster : public Master
      {
      public:
          //重写eightSwordKill函数
          int eightSwordKill()
          {
              int ret = Master::eightSwordKill() * 2;
              
              cout << "NewMaster::eightSwordKill() : " << ret << endl;
              
              return ret;
          }
      };
      
      void field_pk(Master* master, Boss* boss)
      {
          int k = master->eightSwordKill();
          int b = boss->fight();
          
          if( k < b )
          {
              cout << "Master is killed..." << endl;
          }
          else
          {
              cout << "Boss is killed..." << endl;
          }
      }
      
      int main()
      {
          Master master;
          Boss boss;
          
          cout << "Master vs Boss" << endl;
          
          field_pk(&master, &boss);
          
          cout << "NewMaster vs Boss" << endl;
          
          NewMaster newMaster;
          
          field_pk(&newMaster, &boss);
          
          return 0;
      }
      
    • 编译运行

      Master vs Boss
      Master::eightSwordKill() : 8
      Boss::fight() : 10
      Master is killed...
      
      NewMaster vs Boss
      Master::eightSwordKill() : 8
      NewMaster::eightSwordKill() : 16
      Boss::fight() : 10
      Boss is killed...
      
posted @ 2020-10-30 19:42  nxgy  阅读(99)  评论(0编辑  收藏  举报