对于方法的调用,很是令我头疼,什么静态方法,,实例方法,实例虚方法,这里查了很多资料,总结如下:
这里声明,我也是菜鸟,这里只讨论方法的调用相关的技术,属于个人理解,如有错误,请指正
思路:
1 clr在加载类型的过程中方法表是怎么样构建的?
2 在程序调用方法时是怎样确定使用哪个类型的方法表的?
3 在程序调用方法时是怎样确定方法在方法表中的位置的(位于方法表的第几个方法)?
一 、方法在方法表中的排列顺序:继承的实例虚方法、实例虚方法、构造函数、静态方法、实例方法
方法表排列原则:
1 在类的方法表的构造过程中:虚方法总是在子类的方法表中被复制的;实例方法,构造函数,静态方法等其他方法则在子类的方法表中不继承的
2 在类的方法表中:虚方法总是排在方法表的开头位置;继承的虚方法在最前面,新建的虚方法紧随其后(如图)
3 虚方法后边依次排列的是构造函数、静态方法、实例方法
为什么把“继承的实例虚方法”和“实例虚方法”放在方法表的开头位置?在这种情况下每个虚方法在 相关的类的 方法表中 的位置都是不变的(无论是在其在创建方法的类中还是在派生类中):比如一个虚方法在类中的次序是第k个,那么他在其子类或父类(如果父类中有这个方法)中的位置都是第k个。
如果子类中新添加了虚方法,因为在新填的虚方法之前,已经把父类的方法表中的虚方法都复制到了子类的方法表最前面,所以父类中所有的方法在其子类中的位置序号都是不变的。
如果子类中新添加了除了虚方法之外的其他方法(实例方法,构造函数,静态方法等),这些方法也都是排在虚方法之后
以上两点就保证了虚方法无论是在其自身的类、父类、子类中其在方法表中的位置(位于方法表的第几个)都是不变的
结论:方法表中虚方法的排序,可以在类的层次结构中保持虚方法的层次结构,这是实现多态的基础,也就是为什么说继承是实现多态的基础了。
例子:类的定义代码如下:
class Program { static void Main(string[] args) { Father son = new Son(); son.DoWork(); son.DoVirtualWork(); son.DoVirtualAll(); Son.DoStaticWork(); Father aGrandson = new Grandson(); aGrandson.DoWork(); aGrandson.DoVirtualWork(); aGrandson.DoVirtualAll(); Console.ReadKey(); } } public class Father { public void DoWork() { Console.WriteLine("Father.DoWork()"); } public virtual void DoVirtualWork() { Console.WriteLine("Father.DoVirtualWork()"); } public virtual void DoVirtualAll() { Console.WriteLine("Father.DoVirtualAll()"); } } public class Son : Father { public static void DoStaticWork() { Console.WriteLine("Son.DoStaticWork()"); } public new void DoWork() { Console.WriteLine("Son.DoWork()"); } public new virtual void DoVirtualWork() { Console.WriteLine("Son.DoVirtualWork()"); } public override void DoVirtualAll() { Console.WriteLine("Son.DoVirtualAll()"); } } public class Grandson : Son { public override void DoVirtualWork() { Console.WriteLine("Grandson.DoVirtualWork()"); } public override void DoVirtualAll() { Console.WriteLine("Grandson.DoVirtualAll()"); } } public class GrandGrandson : Grandson { public new virtual void DoVirtualWork() { Console.WriteLine("GGson.DovirtualWork()"); } public override void DoVirtualAll() { Console.WriteLine("GGson.DoVirtualAll()"); } }
示例代码