zoukankan      html  css  js  c++  java
  • C# 方法 虚方法的调用浅谈

    我们在面试中经常碰到有关多态的问题,之前我也一直被此类问题所困扰,闹不清到底执行哪个方法。

    先给出一道简单的面试题,大家猜猜看,输出是?

    View Code 
        public class A
        {
            public void MethodF() 
            { 
                Console.WriteLine("A.F"); 
            }
            public virtual void MethodG() 
            { 
                Console.WriteLine("A.G"); 
            }
        }
        public class B : A
        {
            new public void MethodF() 
            { 
                Console.WriteLine("B.F"); 
            }
            public override void MethodG() 
            { 
                Console.WriteLine("B.G"); 
            }
        }
        class Test
        {
            static void Main()
            {
                B b;
                b = new B();
                A a = b;
                a.MethodF();
                b.MethodF();
                a.MethodG();
                b.MethodG();
            }

    首先看一下虚方法的定义(MSDN):

      若一个实例方法的声明中含有 virtual 修饰符,则称该方法为虚拟方法。若其中没有 virtual 修饰符,则称该方法为非虚拟方法。

    以上面题目Test类Main中代码为例,简单说一下CLR创建对象的过程都做了什么事情

    1) 首先,声明一个引用类型变量 b,它仅是一个引用,保存在线程的栈上,用于将来存放B对象的有效地址。此时 b 未指向任何有效的实例,值为null,相关代码为:

         B b;

    2) 接下来,通过new执行对象的创建,即:

         b = new B();
    对象的实例保存在托管堆上,CLR在创建一个新对象的同时,还会创建它的类型对象(如果类型对象不存在)。

      对象实例在堆中的内存包括实例字段、类型对象指针、同步索引块,类型对象指针指向类型对象。

      类型对象在堆中分配的内存包括类型对象指针、同步索引块、静态字段、方法表。

    3)  A a = b;  这行代码首先声明一个类型为A的引用类型变量a,并将其实际地址指向b所指向的对象实例。

    4)  之后就是方法的调用,下面详细说一下C#中方法的调用:

        a.MethodF();

    当调用一个对象的方法时,会直接检查这个对象变量(a)的类型 ,找到堆中的类型对象,查看是否有该方法,没有则通过类型对象的类型对象指针向上回溯查找,直至找到,然后检查该方法是否为虚方法,如果非虚,直接调用,由于MethodF 方法是非虚的,因此直接调用输出A.F。

        a.MethodG();

    如果该方法为虚方法,即有virtual 关键字,则根据对象变量(a),去找到对象的实例类B,查找该类型对象中是否重新实现过该虚方法(override 关键字),如果有,OK执行,如果没有,向上检查其父类,直至找到然后执行,MethodG为虚方法,则会查找实例B,由于B中重写了MethodG,因此此处输出B.G


      通过上面的描述,开始的那道面试题,我们应该轻松可以得出输出,此处就不啰嗦了。 

      一般考多态的面试题中 virtual new override  几个关键字经常出现,new 关键字实现一个新的方法,同时隐藏基类的同名方法。 

     
     
  • 相关阅读:
    CodeForces 510C Fox And Names (拓扑排序)
    Codeforces 1153D Serval and Rooted Tree (简单树形DP)
    HDU 6437 Problem L.Videos (最大费用)【费用流】
    Luogu P3381 (模板题) 最小费用最大流
    Codeforces 741B Arpa's weak amphitheater and Mehrdad's valuable Hoses (并查集+分组背包)
    Codeforces 1144F Graph Without Long Directed Paths (DFS染色+构造)
    HDU 2204 Eddy's 爱好 (容斥原理)
    Codeforces 939E Maximize! (三分 || 尺取)
    Codeforces 938D. Buy a Ticket (最短路+建图)
    CodeForces 959E Mahmoud and Ehab and the xor-MST (MST+找规律)
  • 原文地址:https://www.cnblogs.com/kdalan/p/2523470.html
Copyright © 2011-2022 走看看