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++中支持多态的唯一方式
    被重写的虚函数可表现出多态的特性

  • 相关阅读:
    润乾V4导出TXT时自定义分隔符
    aix系统下的websphere的静默安装
    润乾V4报表放入WEBINF保护目录下如何实现
    初创公司谁来当你们的运维
    无密码身份验证:安全、简单且部署快速
    ASP .NET 如何在 SQL 查询层面实现分页
    世界那么大,你要去看看!
    你真的知道如何定义性能要求么?
    node-firefox 二三事
    轻轻修改配置文件完成 OpenStack 监控
  • 原文地址:https://www.cnblogs.com/-glb/p/11964489.html
Copyright © 2011-2022 走看看