1、当调用一个接口的函数时,系统会去检查这个接口对应实例是什么;
2、找到这个实例后,再去找这个实例对应的实例类是什么(实例类,在虚函数一文里曾说明过);
3、根据这个实例类去检查该实例类是否和接口发生了捆绑(看是否实现了该接口,冒号后面就是);
4、好!如果实例类实现了该接口(发生了捆绑),那么它就在这个实例类中找到接口中所申明的方法的定义,然后执行该方法,然后结束。
5、如果没找到,它就继续往父类去找,直到找到第一个和接口捆绑的父类为止
6、找到后,它再检查这个父类里该方法是否是被定义为虚函数;
7、如果不是,他马上就执行这个方法,然后结束;
8、如果是,麻烦了,系统又要从头来过,去检查该最开始那个实例类里有否重载了父类里的这个虚函数
interface I
{
voidFunc();
}
class A : I
{
publicvirtualvoidFunc()
{
Console.WriteLine("Func In A");
}
}
classB : A , I // 注意这里,用接口来实现类似多重继承的效果
{
publicvoidFunc()
{
Console.WriteLine("Func In B");
}
}
class C : A
{
publicoverridevoidFunc()
{
Console.WriteLine("Func In C");
}
}
class D : A
{
publicnewvoidFunc()
{
Console.WriteLine("Func In D");
}
}
publicstaticvoidmain()
{
I a = newA() ; //申明了接口a,并马上和一个类的实例发生关系了
I b = newB() ; //申明了接口b,并马上和一个类的实例发生关系了
I c = newC() ; //申明了接口c,并马上和一个类的实例发生关系了
I d = newD() ; //申明了接口d,并马上和一个类的实例发生关系了
//检查a的实例类A,发现A和接口I捆绑了,所以执行A的函数Func ,结果: Func In A
a.Func();
// 检查b的实例类B,发现B和接口I捆绑了,所以执行B的函数Func(而不会去执行父类A的,尽管A也
// 实现I接口),结果: Func In B
b.Func();
// 检查c的实例类C,发现其没有和接口I捆绑,系统继续找它的父类. 发现A和I捆绑了,他就去找
// 函数A,发现A是虚拟函数,系统又从头来找类的实例C,发现C重载(override)了Func,好了,马
//上执行该函数. 结果是Func In C
c.Func();
// 检查d的实例类D,发现其没有和接口I捆绑,系统继续找它的父类. 发现A和I捆绑了,他就去找
// 函数A,发现A是虚拟函数,系统又从头来找类的实例D,但是D里没有重载(override)Func(而是
// 用new覆盖了),所以又会到D的父类里找,所以还是执行A的Func(),结果是Func In A
d.Func() ;
}

