• 重载和覆盖


    重载(overloding)和覆盖(overriding)这两个词语对于学习OO开发的人应该不会陌生,也不应该陌生,相反的而应该将这两个的区别弄的一清二楚,话说,其实当年在学习的时候对这两个的的更深入的内容不是很清楚。

    重载是出现在同一个类中的就是函数名一样,而参数个数和类型不一样的,而覆盖是出出现在子类中的,子类用来覆盖父类中的同名函数,这几句话是老师苦口婆心交给我们的,而则两句似乎也成了口头禅。

    多年以后,仔细品味身边的书籍,有一种突如其来的想法,想自己写一写东西,还是看下面的一个例子:

    #include <stdio.h> 
    #include <iostream> 
      
    /**  
    *Shape 
    */
    class CShape 
    { 
    public: 
    CShape(){} 
    virtual ~CShape(){} 
      
    virtual void Draw()
    
    {

    printf("Hello! I am Base!/n");


    }

    }; /** *Point */ class CPoint : public CShape { public: CPoint(){} ~CPoint(){} void Draw() { printf("Hello! I am Point!/n"); } }; /** *Line */ class CLine : public CShape { public: CLine(){} ~CLine(){} void Draw() { printf("Hello! I am Line!/n"); } }; void main() { CShape* shape = new CPoint(); //draw point shape->Draw();//在这里shape将会调用CPoint的Draw()函数 delete shape; shape = new CLine(); //draw Line shape->Draw();//而在这里shape将会调用CLIne 的Draw()函数 delete shape; return ; }

    同一个父类调用同一个方法,结果却是不一样,当然这是我们想要的结果,这种在OOP叫做多态,OO的三大特性之一就有多态这个说法。
    多态:字面的含义是具有多种形式或形态。C++多态有两种形式,动态多态和静态多态;动态多态是指一般的多态,是通过类继承和虚函数机制实现的多态;静态多态是通过模板来实现,因为这种多态实在编译时而非运行时,所以称为静态多态。

    动态多态是我们常用的,其是在运行阶段进行时确定函数的调用,在C++中要达到这个效果,就要使用虚函数,有一个词语,叫迟后绑定或者运行时绑定或者晚绑定,说的就是这个;静态多态是在编译阶段将函数的调用关系就确定了,因此也叫早绑定。

    其实这两个过程也就是高级语言的两个过程,编译和运行,至于这两个过程分别做些什么处理,计算机的书籍上都有很详细的介绍,我也就不罗嗦了。

    在C++中实现这种动态多态常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

    如果不用虚函数,实际会是什么样子呢?

    #include <stdio.h> 
    #include <iostream> 
      
    /**  
    *Shape 
    */
    class CShape 
    { 
    public: 
    CShape(){} 
    virtual ~CShape(){} 
      
     void Draw()
    
    {
    printf("Hello! I am Base!/n");

    } }; /** *Point */ class CPoint : public CShape { public: CPoint(){} ~CPoint(){} void Draw() { printf("Hello! I am Point!/n"); } }; /** *Line */ class CLine : public CShape { public: CLine(){} ~CLine(){} void Draw() { printf("Hello! I am Line!/n"); } }; void main() { CShape* shape = new CPoint(); //draw point shape->Draw();//调用CShape的Draw()函数 delete shape; shape = new CLine(); //draw Line shape->Draw();//调用CShape的Draw()函数 delete shape; return ; }

    如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。

    下面这个例子就是静态多态,在编译阶段就知道要调用的函数:

     

    template <class T> 
    void DrawShape(T* t) 
    { 
    t->Draw(); 
    } 
      
    修改main函数为如下: 
      
    void main() 
    { 
    CShape* shape = new CPoint(); 
    //draw point 
    shape->Draw(); 
      
    DrawShape<CPoint>((CPoint*)shape); 
    delete shape; 
      
    shape = new CLine(); 
    //draw Line 
    shape->Draw(); 
    DrawShape<CLine>((CLine*)shape); 
    delete shape; 
      
      
    return ; 
    }

    对于Java的程序员,也可以实现多态,但是只要子类继承了父类,并且在子类中重写了父类中的同名方法,那么将子类作为父类的变量值的时候,运行的时候会调用子类的方法而不是父类的,为什么会出现这种情况?如果按照C++的这种写法,那么只要不是虚函数,就调用的一定是父类的,答案在于Java中的函数都是虚函数。

  • 相关阅读:
    C#基础视频教程4.1 如何编写简单的计算器
    C#基础视频教程3.3 常见控件类型和使用方法
    C#基础视频教程3.2 常见控件类型和使用方法
    C#基础视频教程3.1 常见控件类型和使用方法
    C#基础视频教程2 常见数据类型和属性方法
    C#基础视频教程1 背景知识和安装配置
    为什么我的淘宝排名会突然下降?
    Idea项目如何迁移到Eclipse
    myeclipse部署项目的时候报No projects are available for deployment to this server但是项目明明存在
    idea如何将项目以eclipse保存
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/3163534.html
Copyright © 2020-2023  润新知