A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qly2046 中级黑马   /  2014-1-2 17:58  /  3079 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 qly2046 于 2014-1-3 09:46 编辑

今天视频面试,吕老师问到了虚方法?由于复习没有涉及到这方面,所以没有回答。
请问什么是虚方法?作用是什么?怎么使用?谢谢

评分

参与人数 1技术分 +1 收起 理由
V_John + 1

查看全部评分

9 个回复

倒序浏览
当类中的方法声明前加上了virtual修饰符,我们称之为C#虚拟方法 ,反之为非虚。使用了virtual修饰符后,不允许再有static、abstract或override修饰符。对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变。而对于虚方法,它的执行方式可以被派生类改变,这种改变是通过方法的重载来实现的。

    下面的例子说明了C#虚拟方法与非虚方法的区别。

    例子:

using System;  
class A  
{  
   public void F(){Console.WriteLine("A.F");}  
   public virtual void G(){Console.WriteLine("A.G");}  
}  
class B:A  
{  
   new public void F(){Console.WriteLine("B.F");}  
   public override void G(){Console.WriteLine("B.G");}  
}  
class Test  
{  
   static void Main()  
   {  
      B b=new B();  
      A a=b;  
      a.F();  
      b.F();  
      a.G();  
      b.G();  
   }  
}
    例子中,A类提供了两个方法:非虚的F和C#虚拟方法 G.类B则提供了一个新的非虚的方法F,从而覆盖了继承的F;类B同时还重载了继承的方法G.那么输出应该是:

    A.F

    B.F

    B.G

    B.G

    注意到本例中,方法a.G()实际调用了B.G,而不是A.G.这是因为编译时值为A,但运行时值为B,所以B完成了对方法的实际调用。
回复 使用道具 举报
恭喜你顺利通过面试~!
回复 使用道具 举报
可以用virtual实现多态性的一种,virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。在调用的时候,根据堆中对象的实际类型调用对应的虚拟方法

你面试的是哪一期的啊,亲
回复 使用道具 举报
yuanlianxi03 发表于 2014-1-2 19:04
可以用virtual实现多态性的一种,virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派 ...

11期,已经录取了。你呢?
回复 使用道具 举报
卖火柴 发表于 2014-1-2 18:43
恭喜你顺利通过面试~!

谢谢了,已经顺利被录取了!你怎么样呀?代码一大坨君:lol
回复 使用道具 举报
qly2046 发表于 2014-1-2 19:17
谢谢了,已经顺利被录取了!你怎么样呀?代码一大坨君

我妈说 快过年呀,年后再去,上·10来天再回来。费周折的,自己多看看,把课程提前学下, 才保险能跟上。
回复 使用道具 举报
qly2046 发表于 2014-1-2 19:16
11期,已经录取了。你呢?

我准备报12期,现在还没开始报名,正在苦苦等待中
回复 使用道具 举报
虚方法是实现多态的一种手段,通过声明在virtual ,在派生类种声明为override,   那么在执行该方法时,就采用迟绑定技术,向派生类往下一个一个的去找,直到找到他的实际创建类型类或不再override

评分

参与人数 1技术分 +1 收起 理由
V_John + 1

查看全部评分

回复 使用道具 举报
--virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
--virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用。
  1. class TestClass
  2. {
  3.     public class Dimensions
  4.     {
  5.         public const double PI = Math.PI;
  6.         protected double x, y;
  7.         public Dimensions()
  8.         {
  9.         }
  10.         public Dimensions(double x, double y)
  11.         {
  12.             this.x = x;
  13.             this.y = y;
  14.         }

  15.         public virtual double Area()
  16.         {
  17.             return x * y;
  18.         }
  19.     }

  20.     public class Circle : Dimensions
  21.     {
  22.         public Circle(double r) : base(r, 0)
  23.         {
  24.         }

  25.         public override double Area()
  26.         {
  27.             return PI * x * x;
  28.         }
  29.     }

  30.     class Sphere : Dimensions
  31.     {
  32.         public Sphere(double r) : base(r, 0)
  33.         {
  34.         }

  35.         public override double Area()
  36.         {
  37.             return 4 * PI * x * x;
  38.         }
  39.     }

  40.     class Cylinder : Dimensions
  41.     {
  42.         public Cylinder(double r, double h) : base(r, h)
  43.         {
  44.         }

  45.         public override double Area()
  46.         {
  47.             return 2 * PI * x * x + 2 * PI * x * y;
  48.         }
  49.     }

  50.     static void Main()
  51.     {
  52.         double r = 3.0, h = 5.0;
  53.         Dimensions c = new Circle(r);
  54.         Dimensions s = new Sphere(r);
  55.         Dimensions l = new Cylinder(r, h);
  56.         // Display results:
  57.         Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
  58.         Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
  59.         Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
  60.         }
  61.     }
  62.     /*
  63.         Output:
  64.         Area of Circle   = 28.27
  65.         Area of Sphere   = 113.10
  66.         Area of Cylinder = 150.80
  67.     */
复制代码



评分

参与人数 1技术分 +1 收起 理由
V_John + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马