用例子来彻底搞明白Virtual 和 非 virtual(C#)

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

virtual出问题主要是由于声明对象的类和对象实际所属的类不是一个类,一般都是父类和子类的关系。比如:
ClassParent obj = new ClassSub(),这是根源。

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

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

None.gif using  System; 
None.gif
None.gif
None.gif
public   class  ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public string s1; 
InBlock.gif
InBlock.gif
// virtual public void VirFun() 
InBlock.gif

InBlock.gif
public void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{ Console.WriteLine( s1 );} 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  ClassBoy : ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public new void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gifbase.VirFun();} 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  ClassGirl : ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public new void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif
InBlock.gif
InBlock.gif
base.VirFun(); 
InBlock.gif
InBlock.gifConsole.WriteLine( s1 ); 
InBlock.gif
ExpandedSubBlockEnd.gif}
 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  Test 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public static void Main() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif
InBlock.gif
InBlock.gifClassFather a 
= new ClassFather(); 
InBlock.gif
InBlock.gifa.s1 
= "father"
InBlock.gif
InBlock.gifa.VirFun(); 
InBlock.gif
InBlock.gif
InBlock.gifClassFather b 
= new ClassBoy(); 
InBlock.gif
InBlock.gifb.s1 
= "boy"
InBlock.gif
InBlock.gifb.VirFun(); 
InBlock.gif
InBlock.gif
InBlock.gifClassFather c 
= new ClassGirl(); 
InBlock.gif
InBlock.gifc.s1 
= "girl"
InBlock.gif
InBlock.gifc.VirFun(); 
InBlock.gif
ExpandedSubBlockEnd.gif}
 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif

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

3,如果一个父类的方法是virtual,子类不是用override,而是用new来覆盖了,那么运行子类的时候,还是执行声明的类的方法。比如下面的例子中,girl类对象就是。
None.gif using  System; 
None.gif
None.gif
None.gif
public   class  ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public string s1; 
InBlock.gif
InBlock.gif
virtual public void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{ Console.WriteLine( s1 );} 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  ClassBoy : ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public override void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gifbase.VirFun();} 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  ClassGirl : ClassFather 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public new void VirFun() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif
InBlock.gif
InBlock.gif
base.VirFun(); 
InBlock.gif
InBlock.gifConsole.WriteLine( s1 ); 
InBlock.gif
ExpandedSubBlockEnd.gif}
 
InBlock.gif
ExpandedBlockEnd.gif}
 
None.gif
None.gif
None.gif
public   class  Test 
None.gif
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif
InBlock.gif
public static void Main() 
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif
InBlock.gif
InBlock.gifClassFather a 
= new ClassFather(); 
InBlock.gif
InBlock.gifa.s1 
= "father"
InBlock.gif
InBlock.gifa.VirFun(); 
InBlock.gif
InBlock.gif
InBlock.gifClassFather b 
= new ClassBoy(); 
InBlock.gif
InBlock.gifb.s1 
= "boy"
InBlock.gif
InBlock.gifb.VirFun(); 
InBlock.gif
InBlock.gif
InBlock.gifClassFather c 
= new ClassGirl(); 
InBlock.gif
InBlock.gifc.s1 
= "girl"
InBlock.gif
InBlock.gifc.VirFun(); 
InBlock.gif
ExpandedSubBlockEnd.gif}
 
InBlock.gif
ExpandedBlockEnd.gif}

None.gif


没有VS.Net,代码写的有些不那么美观,将就看吧。来这里好长时间了,没有写点.Net的文章,担心那天把我驱逐出去,写这篇来说说一些概念性的东西吧。

转载于:https://www.cnblogs.com/Hacker/archive/2004/08/10/31774.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值