zoukankan      html  css  js  c++  java
  • C#虚函数virtual详解

     在面向对象编程中,有两种截然不同的继承方式:实现继承和接口继承。在实现继承时候,在Java中,所有函数默认都是virtual的,而在C#中所有函数并不默认为virtual的,但可以在基类中通过声明关键字virtual,就可以在其派生类中通过关键字override重写该函数。

         重写后的virtual函数依旧是virtual函数。由于virtual只对类中的实例函数成员有意义,所以成员字段和静态函数都不能声明为virtual,也不能与override和abstract一起用。C#中可以设置virtual属性、索引器或事件,例如  

    virtual string Name
    {
    get;
    set;
    }
    无virtual和override关键字“重写”

         如果签名后的函数在基类中都进行了声明,却没有用virtual和override关键字,例如:

    class Base1
    {
    public void printMethod()
    {
    Console.WriteLine("base1");
    }
    }

    class Derived1 : Base1
    {
    public void printMethod()
    {
    Console.WriteLine("derived1");
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    Base1 base1 = new Base1();
    Derived1 derived = new Derived1();

    base1.printMethod();
    derived.printMethod();

    base1 = new Derived1();
    base1.printMethod();


    Console.ReadLine();
    }
    }


     输出为:
              base1

              derived1

              base1

         由于方法相同,在用子类新方法编译代码时候,程序在应该调用哪种方法上就会有潜在的冲突,此时编译器会发出警告,认为子类Derived1的printMethod()隐藏了父类Base1的printMethod();此时可以从新命名子类Derived1的printMethod(),这是最好的解决办法,其次可以通过关键字new隐藏此方法来控制版本。

         这是所谓的无virtual和override的“重写”其实只是隐藏。

    有virtual和override关键字“重写”

       在派生类中添加关键字virtual和override,实现对基类的重写:

    class Base1
    {
    public virtual void printMethod()
    {
    Console.WriteLine("base1");
    }
    }

    class Derived1 : Base1
    {
    public override void printMethod()
    {
    Console.WriteLine("derived1");
    }
    }


    class Program
    {
    static void Main(string[] args)
    {
    Base1 base1 = new Base1();
    Derived1 derived = new Derived1();


    base1.printMethod();
    derived.printMethod();

    base1 = new Derived1();
    base1.printMethod();
    Console.ReadLine();
    }
    }

    此时,输出的结果是:
                          base1

                         derived1

                         derived1

      在类的定义中,申明时定义的类叫申明类,执行实例化时候定义的类叫实例类。例如:

                                        Base1 base1 = new Derived1 ();其中Base1叫做申明类,而Derived1则是实例类。

      此时编译器具体的检查的流程如下

    1、当调用函数时,系统会直接去检查申明类,看所调用的函数是否为虚函数;

    2、如果不是,那么它就直接执行该函数。如果是virtual函数,则转去检查对象的实例类。

    3.在实例类中,若有override的函数,则执行该函数,如果没有,则依次上溯,按照同样步骤对父类进行检查,知道找到第一个override了此函数的父类,然后执行该父类中的函数。(星梦《C#虚函数virtual详解收藏》)

     由此可知,

    若子类Derived1中未添加关键字override,则直接在base1中执行父类同名函数,此时输出结果为:

        base1

        derived1

        base1

    依次类推,若有Derived2继承了Derived1,即:

    class Derived2 : Derived1

    {

    public void printMethod(){

    Console.WriteLine("derived2");

    }

    }

    在Program类 中执行

    base1 = new Derived2();

    base1.printMethod();

               

    则此时执行的是Derived2中override的同名函数printMethod()。
    ---------------------
    作者:songsz123
    来源:CSDN
    原文:https://blog.csdn.net/songsz123/article/details/7369913
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    C++ 11 :override 关键字的使用
    vsphere部署说明
    Windows 下部署Subversion
    Centos 7 最小化部署zabbix
    在vmware中安装mac os
    如何将OS dmg文件制作成U盘启动
    HDU1518(dfs)java/ c++
    HDU1010(bfs)
    HDU1495(bfs)
    HD1285(拓扑排序)
  • 原文地址:https://www.cnblogs.com/yuer20180726/p/10382566.html
Copyright © 2011-2022 走看看