C#中接口其实就是一种协议,其他继承该接口的类,必须严格按照接口协议去履行实现接口中定义的所有的方以及属性,如果继承的接口有父继承,则继承类中也要对接口的父继承中约定的所有的方法与属性进行实现,否则编译器将会报错。
一个接口的数据成员的定义,不能显示的包含public等修饰符,否则编译器将会报错,因为接口内的每个方法或属性成员都是隐式的进行的public声明。接口不能被实例化但是继承接口的类也就是接口的继承类可以被实例化。
1、当调用一个接口的函数时,系统会去检查这个接口对应实例是什么;
2、找到这个实例后,再去找这个实例对应的实例类是什么(实例类,在虚函数一文里曾说明过);
3、根据这个实例类去检查该实例类是否和接口发生了捆绑(看是否实现了该接口,冒号后面就是);
4、好!如果实例类实现了该接口(发生了捆绑),那么它就在这个实例类中找到接口中所申明的方法的定义,然后执行该方法,然后结束。
5、如果没找到,它就继续往父类去找,直到找到第一个和接口捆绑的父类为止
6、找到后,它再检查这个父类里该方法是否是被定义为虚函数;
7、如果不是,他马上就执行这个方法,然后结束;
8、如果是,麻烦了,系统又要从头来过,去检查该最开始那个实例类里有否重载了父类里的这个虚函数……
- interface I
- {
- void Func();
- }
- class A:I
- {
- public virtual void Func()
- {
- Console.WriteLine("Func In A");
- }
- }
- //注意这里,用接口来实现类似多重继承的效果
- class B:A,I
- {
- public void Func()
- {
- Console.WriteLine("Func In B");
- }
- }
- class C:A
- {
- public override void Func()
- {
- Console.WriteLine("Func In C");
- }
- }
- class D:A
- {
- public new void Func()
- {
- Console.WriteLine("Func In D");
- }
- }
- public static void main()
- {
- I a = new A();
- I b = new B();
- I c = new C();
- I d = new 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();
- }
http://blog.sina.com.cn/s/blog_4ff1251f0100axam.html