您好,欢迎来到微智科技网。
搜索
您的当前位置:首页深入理解virtual/new/override 这些关键字的意义

深入理解virtual/new/override 这些关键字的意义

来源:微智科技网
 1

Derived dev = new Derived();
问:屏幕的输出是多少?

输出:value != 42, what is wrong?
原因:在执行Derived的构造函数之前,要先执行父类Base的构造函数,而在Base的构造函数中,调用了虚方法Method1,此时CLR会监测到this的运行时类型为Derived,因此在调用(this.)Method1时,实际调用的是Derived.Method1()方法;而此时还没有执行父类Derived构造函数,因此value还没有赋值(默认为0),因此要执行语句:Console.WriteLine("value != 42, what is wrong?");


下面详细介绍virtual/new/override 这些关键字的意义

 

2. new:子类在继承了父类后,可以用new来隐藏父类中的方法。此时,在子类的方法表(Mathod Table)中,仍然保留父类中该方法的方法槽(slot,.net对象模型中,类型中的每个方法在方法表中都占用一个方法槽)。因此,我们仍然可以将子类的引用强制转换成父类的引用,来调用父类中的非virtual或virtual方法。例如:下面第四题中的代码,如果我们将override改成new,则最终结果是:执行父类Base的Method1,输出“In Base's Method1()”。

3. override:子类在继承了父类后,可以用override来重写父类中的方法。此时,在子类的方法表中,不再保留父类中该方法的方法槽。当我们将子类的引用强制转换成父类的引用,来试图调用父类中的virtual方法时,实际上是不能执行成功的,因为CLR检测到此时对象的运行时类型是子类类型,于是将调用分派(dispatch)到子类的方法上。例如:下面第四题中的代码,在父类Base中调用子类中已重写的Method1方法,CLR检测到此时this的运行时类型为Derived,因此仍然会调用Derived中重写的Method1。

 

例如:上面中的例子,可以用VS2005的SOS扩展来分析Base/Derived的对象模型(调试过程中,在“即使窗口”中输入的命令用蓝色显示,其余的为输出信息)(有关SOS的使用,可以参考我以前写的:《》)。可以看出,在使用override的情况下,子类的方法表中只有一个Method1方法槽(下面以红色显示的部分),子类Derived覆盖重写了父类Base的Method1方法;而在使用new的情况下,子类的方法表中有两个Method1方法槽,子类Derived仅仅只是对外隐藏了父类Base中的Method1。

1. override

!dumpheap -type Derived
PDB symbol for mscorwks.dll not loaded
 Address       MT     Size
013f8828 00a531f0       12    
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
00a531f0        1           12 Bingosoft.Training2007.CSharp.Derived
Total 1 objects 

!DumpMT -MD 00a531f0
EEClass: 00a513f8
Module: 00a52c14
Name: Bingosoft.Training2007.CSharp.Derived
mdToken: 02000004 (H:\Training\DotNetExam\DotNetExam\bin\Debug\DotNetExam.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 6
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
79354bec   7913bd48   PreJIT System.Object.ToString()
793539c0   7913bd50   PreJIT System.Object.Equals(System.Object)
793539b0   7913bd68   PreJIT System.Object.GetHashCode()
7934a4c0   7913bd70   PreJIT System.Object.Finalize()
00a53248   00a531e8      JIT Bingosoft.Training2007.CSharp.Derived.Method1()
00a53238   00a531e0      JIT Bingosoft.Training2007.CSharp.Derived..ctor()

 

2. 如果我们将Derived类中的override改成new,得到的分析结果如下:

!dumpheap -type Derived
PDB symbol for mscorwks.dll not loaded
 Address       MT     Size
013f8828 00a531f0       12    
total 1 objects
Statistics:
      MT    Count    TotalSize Class Name
00a531f0        1           12 Bingosoft.Training2007.CSharp.Derived
Total 1 objects

!DumpMT -MD 00a531f0
EEClass: 00a513f8
Module: 00a52c14
Name: Bingosoft.Training2007.CSharp.Derived
mdToken: 02000004 (H:\Training\DotNetExam\DotNetExam\bin\Debug\DotNetExam.exe)
BaseSize: 0xc
ComponentSize: 0x0
Number of IFaces in IFaceMap: 0
Slots in VTable: 7
--------------------------------------
MethodDesc Table
   Entry MethodDesc      JIT Name
79354bec   7913bd48   PreJIT System.Object.ToString()
793539c0   7913bd50   PreJIT System.Object.Equals(System.Object)
793539b0   7913bd68   PreJIT System.Object.GetHashCode()
7934a4c0   7913bd70   PreJIT System.Object.Finalize()
00a531b0   00a53150      JIT Bingosoft.Training2007.CSharp.Base.Method1()
00a53240   00a531e0      JIT Bingosoft.Training2007.CSharp.Derived..ctor()
00a53250   00a531e8     NONE Bingosoft.Training2007.CSharp.Derived.Method1()

 

转载于:https://www.cnblogs.com/happyhippy/archive/2007/07/22/827583.html

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务