zoukankan      html  css  js  c++  java
  • 第49课 多态的概念和意义

    函数重写回顾
    父类中被重写的函数依然会继承给子类
    子类中重写的函数将覆盖父类中的函数
    通过作用域分辨符(::)可以访问到父类中的函数
    Child c;
    Parent* p = &c;

    c.Parent::print(); //从父类中继承
    c.print(); //在子类中重写

    p->print(); //父类中定义

    面向对象中期望的行为
    -根据实际的对象类型判断如何调用重写函数
    -父类指针(引用)指向
      父类对象则调用父类中定义的函数
      子类对象则调用子类中定义的重写函数

    面向对象中多态的概念
    -根据实际的对象类型决定函数调用的具体目标
    -同样的调用语句在实际运行时有多种不同的表现形态
    p->print():
    1)p指向父类对象
    void print()
    {
      cout << "I'm Parent. " <<endl;
    }

    2)p指向子类对象
    void print()
    {
      cout << "I'm Child." <<endl;
    }

    C++语言直接支持多态的概念
    -通过使用virtual关键字对多态进行支持
    -被virtual声明的函数被重写后具有多态特性
    -被virtual声明的函数叫做虚函数

    多态的初体验

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Parent
    {
    public:
        virtual void print()//加上virtual关键字,说明print函数在后续的继承中有可能被重写。因此要注意,调用这个函数的时候要考虑要不要展示多态的行为。
        {                   //编译器在发现virtual这个关键字后,会进一步思考,不会为了安全直接草率地调用父类中的print函数实现。
            cout << "I'm Parent." << endl;
        }
    };
    
    class Child : public Parent
    {
    public:
        void print()  //由于继承于Parent类,所以说print函数也是一个虚函数,虽然virtual没有显示的写出来。在实际的工程中,将virtual省掉,当然如果不嫌麻烦,也可以写。
        {
            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;
    }

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

    理论中的概念
    -静态联编
      在程序的编译期间就能确定具体的函数调用
      如:函数重载
    -动态联编
      在程序实际运行后才能确定具体的函数调用
      如:函数重写

    #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;
    }

     小结:

    函数重写只可能发生在父类与子类之间
    根据实际对象的类型确定调用的具体函数
    virtual关键字是C++中支持多态的唯一方式
    被重写的虚函数可表现出多态的特性

  • 相关阅读:
    剑指Offer-30.连续子数组的最大和(C++/Java)
    剑指Offer-29.最小的K个数(C++/Java)
    UVA 1616 Caravan Robbers 商队抢劫者(二分)
    UVA 10570 Meeting with Aliens 外星人聚会
    UVA 11093 Just Finish it up 环形跑道 (贪心)
    UVA 12673 Erratic Expansion 奇怪的气球膨胀 (递推)
    UVA 10954 Add All 全部相加 (Huffman编码)
    UVA 714 Copying Books 抄书 (二分)
    UVALive 3523 Knights of the Round Table 圆桌骑士 (无向图点双连通分量)
    codeforecs Gym 100286B Blind Walk
  • 原文地址:https://www.cnblogs.com/-glb/p/11964489.html
Copyright © 2011-2022 走看看