对于Virtual的使用,有时候总有些犹豫,特别是最近学的东西太杂,今天化了点时间,把C#里面的Virtual彻底搞明白了。


virtual出问题主要是由于声明对象的类和对象实际所属的类不是一个类,一般都是父类和子类的关系。比如:

ClassParent obj = new ClassSub(),这是根源。


virtual和非virtual关键是在运行时候,而不是在编译时候。


1, 如果方法不是virtual的,编译器就使用声明的类对应的类型,也就是说,不是virtual的,在编译时候,就定了。比如下面的例子:子类的方法都没有执行,执行的全部都是父类的方法。运行的结果是

father

boy

girl


using System;

public class ClassFather

{

 public string s1;

 // virtual public void VirFun()

 public void VirFun()

 { Console.WriteLine( s1 );}

}


public class ClassBoy : ClassFather

{

 public new void VirFun()

 { base.VirFun();}

}

public class ClassGirl : ClassFather

{

 public new void VirFun()

 {

  base.VirFun();

  Console.WriteLine( s1 );

 }

}

public class Test

{

 public static void Main()

 {

  ClassFather a = new ClassFather();

  a.s1 = "father";

  a.VirFun();

  ClassFather b = new ClassBoy();

  b.s1 = "boy";

  b.VirFun();


  ClassFather c = new ClassGirl();

  c.s1 = "girl";

  c.VirFun();

 }

}

2, 如果方法是Virtual的,然后子类使用了override, 编译器就生产代码。然后,在运行的时候,进行检测,看对象属于哪个类,然后调用这个类的方法。 这个是最常用的方法,基本上所有书上说的就是这个,我就不多此一举了。


3,如果一个父类的方法是virtual,子类不是用override,而是用new来覆盖了,那么运行子类的时候,还是执行声明的类的方法。比如下面的例子中,girl类对象就是。

using System;

public class ClassFather

{

 public string s1;

 virtual public void VirFun()

 //public void VirFun()

 { Console.WriteLine( s1 );}

}


public class ClassBoy : ClassFather

{

 public new void VirFun()

 { base.VirFun();}

}

public class ClassGirl : ClassFather

{

 public new void VirFun()

 {

  base.VirFun();

  Console.WriteLine( s1 );

 }

}

public class Test

{

 public static void Main()

 {

  ClassFather a = new ClassFather();

  a.s1 = "father";

  a.VirFun();

  ClassFather b = new ClassBoy();

  b.s1 = "boy";

  b.VirFun();


  ClassFather c = new ClassGirl();

  c.s1 = "girl";

  c.VirFun();

 }

}