zoukankan      html  css  js  c++  java
  • 多态与继承_16

    一。函数重写

      1.在子类中定义与父类中原型相同的函数

      2.函数重写只发生在父类与子类之间

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    
    class Parent
    {
        public:
            void Print()
            {
                cout << "Parent()" << endl;    
            }
    
    };
    
    class Child : public Parent
    {
        public:
            void Print()
            {
                cout <<"Child()"<< endl;    
            }
    };
    
    void run()
    {
        Child child;
        child.Print();
    }
    
    int main(int argc, char *argv[])
    {
        run();
        
        cout << "Press the enter key to continue ...";
        cin.get();
        return EXIT_SUCCESS;
    }

      3.父类中被重写的函数依然会继承给子类

      4.默认情况下子类的重写函数会掩藏父类的函数

      5.通过作用域分辨符::可以访问到父类中被隐藏的函数

    二。当函数重写遇上了赋值兼容性原则

    void run()
    {
        Child child;
        Parent* pp = &child;
        Parent& rp = child;
        
        child.Print();
        pp -> Print();
        rp.Print();
    }

    问题所在:

      1.在C++和C相同,是静态编译型语言

      2.在编译时,编译器自动根据指针的类型判断指向是一个什么样的对象

      3.所以编译器认为父类指针是指向的父类对象(根据赋值兼容性原则,则这个假设合理)

      4.由程序没有执行,所以不知道父类指针指向的具体是父类对象还是子类对象

      5.从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调父类的成员函数。

    三。多态的本质

      1.面向对象的新需求

       a.根据实际的对象类型来判断重写函数的调用

       b.父类对象指向父类的函数。

      2.面向对象中的多态:

        根据实际的对象类型决定函数调用语句的具体调用目标

      3.c++中通过virtual 关键字对多态进行支持

        使用virtual声明的函数被重写后即可展现多态特性 - 这就是传说中的虚函数

    #include <cstdlib>
    #include <iostream>
    
    using namespace std;
    
    class Boss
    {
    private:
        static Boss* cInstance;
        
        Boss()
        {
        }
    public:
        static Boss* GetInstance()
        {
            if( cInstance == NULL )
            {
                 cInstance = new Boss();
            }
            
            return cInstance;
        }
        
        int fight()
        {
            cout<<"Boss::fight()"<<endl;
            return 10;
        }
    };
    
    Boss* Boss::cInstance = NULL;
    
    class Master
    {
    public:
        virtual int eightSwordKill()
        {
            cout<<"Master::eightSwordKill()"<<endl;
            return 8;
        }
    };
    
    class NewMaster : public Master
    {
    public:
        virtual int eightSwordKill()
        {
            cout<<"NewMaster::eightSwordKill()"<<endl;
            return Master::eightSwordKill() * 2;
        }
    };
    
    void fieldPK(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(int argc, char *argv[])
    {
        Boss* boss = Boss::GetInstance();
        
        cout<<"Master vs Boss"<<endl;
        
        Master master;
        
        fieldPK(&master, boss);
        
        cout<<"New Master vs Boss"<<endl;
        
        NewMaster newMaster;
        
        fieldPK(&newMaster, boss);
        
        cout << "Press the enter key to continue ...";
        cin.get();
        return EXIT_SUCCESS;
    }

    四。小结

      1.函数重写是面向对象中很可能发生的情形

      2.函数重写只可发生在父类和子类之间

      3.需要根据实际对象的类型确定调用的具体函数

      4.virtual 关键字是c++中支持多态的唯一方式

      5.被重写的虚函数即可表现多态的特性。

  • 相关阅读:
    @字节跳动8年老Android面试官谈;Context都没弄明白凭什么拿高薪?
    @阿里面试官:Android面试这些原理都给我讲明白了,最低都是20k起步!
    @以后面试官再问你三次握手和四次挥手,直接把这一篇文章丢给他
    @备战2020年金三银四,看这一篇面试文章就够了(合适各级Java人员)
    字节跳动面试,第三面挂了,这原因我服了!
    太可惜了,四面字节跳动,我的offer竟被一道“算法题”给拦截了
    @java2019面试题北京
    @2019.07 Android 面试真题集锦
    2018 Java线程热门面试题,你知道多少?
    阿里大厂的148道核心面试题,(程序员必备学习方向)offer收割机 全会月薪50k不难
  • 原文地址:https://www.cnblogs.com/lvxiaoning/p/7650359.html
Copyright © 2011-2022 走看看