接口可以认为是属于不同继承树的代码之间的行为约定。C#的接口相当于是一种特殊的抽象类,这种抽象类的内部只有虚方法。
一 接口的使用
a) 接口内部可以包含方法、属性、索引器和事件,这些成员都不在接口中实现。接口内部的成员默认都是公开的,而且如果用public修饰还会报编译错误。
b) C#不支持多继承,但可以实现多个接口。
c) 有时会遇到这样的需求:要继承某个接口,但又不想公开接口相关的方法。这时可以使用Name Hiding特性。比如有IDataBound接口
对接口方法的实现除了一般的public void Bind()形式外,还可以这样
把public修饰符去掉,然后写成void IDataBound.Bind()
二 重名问题
C#不支持多继承的原因之一是为了避免重名问题。但因为接口的存在,仍然会有重名的情况出现。比如ISerializable和IDataStore都约定了SaveData方法。
如果一个类同时实现了这两个接口,要如何区分两个Save方法呢,做法与之前的Name Hiding类似
可以在方法前面加上接口类型
三 继承与接口带来的问题
a) 基类的方法与接口的方法同名
本来EditBox类要继承IDataBound接口就必须实现Serialize方法,但这种情况不去实现竟然也能编译通过。因为基类的Serialize方法把编译器欺骗了。
b) 派生类的方法与基类继承的接口的方法同名
比如有接口和方法ITest.Foo(),然后基类实现了ITest接口
上面代码的执行结果会是:
调用哪个Foo()方法取决于当前所持有的引用,调用myDrived.Foo()时,持有MyDerived对象的引用;当转换为ITest接口后,编译test.Foo()时,编译器会上溯继承树,直到找到实现了ITest接口的类。
为了避开这些坑,在使用接口时最好具有明确的转换。
四 接口的合并
有时如果需要同时实现多个接口,就可以将这些接口合并为一个,感觉这就是接口的继承。合并后的接口会带有之前接口的所有成员,还可以添加新的成员。