从http://hacker.cnblogs.com/archive/2004/08/10/31774.aspx看到了Virtual的用法,结合自己的理解整理如下:
1. 如果方法不是virtual的,编译器就使用声明的类对应的类型,也就是说,不是virtual的,在编译时候,就定了。比如下面的例子:子类的方法都没有执行,执行的全部都是父类的方法。
运行的结果:
parent
son
daughter
using System;
using System.Collections.Generic;
using System.Text;
namespace VirtualTest
{
public class ClassParent
{
public string s1;
public void VirFun()
{
Console.WriteLine(s1);
}
}
public class ClassSon : ClassParent
{
public new void VirFun()
{
Console.WriteLine("son:" + s1);
}
}
public class ClassDaughter : ClassParent
{
public new void VirFun()
{
Console.WriteLine("girl:" + s1);
}
}
public class Test
{
public static void Main()
{
ClassParent a = new ClassParent();
a.s1 = "parent";
a.VirFun();
ClassParent b = new ClassSon();
b.s1 = "son";
b.VirFun();
ClassParent c = new ClassDaughter();
c.s1 = "daughter";
c.VirFun();
Console.Read();
}
}
}
2. 如果方法是Virtual的,然后子类使用了override,编译器就生产代码。然后,在运行的时候,进行检测,看对象属于哪个类,然后调用这个类的方法。这个是最常用的方法,基本上所有书上说的就是这个,我就不多此一举了。
3.3如果一个父类的方法是virtual,子类不是用override,而是用new来覆盖了,那么运行子类的时候,还是执行声明的类的方法。比如下面的例子中,daughter类对象就是。
运行结果:
parent
son: son
daughter
using System;
using System.Collections.Generic;
using System.Text;
namespace VirtualTest
{
public class ClassParent
{
public string s1;
public virtual void VirFun()
{
Console.WriteLine(s1);
}
}
public class ClassSon : ClassParent
{
public override void VirFun()
{
Console.WriteLine("son:" + s1);
}
}
public class ClassDaughter : ClassParent
{
public new void VirFun()
{
Console.WriteLine("girl:" + s1);
}
}
public class Test
{
public static void Main()
{
ClassParent a = new ClassParent();
a.s1 = "parent";
a.VirFun();
ClassParent b = new ClassSon();
b.s1 = "son";
b.VirFun();
ClassParent c = new ClassDaughter();
c.s1 = "daughter";
c.VirFun();
Console.Read();
}
}
}
补充:
关于1:无virtual时,编译期就确定方法的类型了。也即:无法实现多态了。
关于2:有vitual时 , 方法在运行时确定类型。可以实现多态 , 只要子类override基类的vitual方法。
关于3:
new与virtual并没有必然的联系。从字面上看,new声明的方法是一个“新”方法,与基类完全没有关系(虽然不幸与基类的某个方法同名同 参)。也即:通过向上转型(如:基类 引用名=new 子类())得到的引用将无法看到子类中new出来的方法。所以会出现第3点中的结果。