目录:
13.1 类和接口继承
13.2 定义接口
13.3 继承接口
13.4 关于调用接口方法的更多探讨
13.5 隐式和显示接口方法实现(幕后发生的事情)
13.6 泛型接口
13.7 泛型和接口约束
13.8 实现多个具有相同方法名称和签名的接口
13.9 用显示接口方法实现来曾强编译时类型安全性
13.10 谨慎使用显示接口方法实现
13.11 设计:基本类型
13.1 类和接口继承
从Object派生的人任何类实际都继承了:
方法签名:使代码认为自己是在操作Object类的实例,但实际操作的可能是其他类的实例。
方法实现:使开发人员定义Object的派生类是不必手动实现Object的方法。
类继承的一个重要特定是,凡是能使用基类型实例的地方,都能使用派生类型的实例。接口继承的一个重要特点是,凡是能使用具名接口类型的实例的地方,都能使用实现了接口的一个类型的实例。
13.2 定义接口
接口对一组方法签名进行了统一命名。接口还能定义事件,无参属性和有参属性(C#索引器) 。接口不能定义任何构造器方法,也不能定义任何实例字段。
CLR允许定义静态方法,静态字段,常量和静态构造器,但符合CLS标准的接口不允许,因为有的编程语言不能定义或访问它们。
13.3 继承接口
在对象上调用接口方法时,调用的是该方法在该对象的类型中的实现。
13.4 关于调用接口方法的更多探讨
CLR允许定义接口类型的字段,参数或局部变量。使用接口类型的变量可以调用该接口定义的方法。
和引用类型相似,值类型可实现零个或多个接口。但值类型的实例在转换为接口类型时必须装箱。这是由于接口变量时引用,必须指向堆上的对象,使CLR能检查对象的类型指针,从而判断对象的确切类型,调用已装箱值类型的接口方法时,CLR会跟随对象的类型对象指针找到对象的方法表,从而调用正确地方法。
13.5 隐式和显示接口方法实现(幕后发生的事情)
在C#中,将定义方法的那个接口的名称作为方法名前缀,就会创建显示接口方法实现(Explicit Interface Method Implementation,EIMI)。EIMI方法不能标记为virual,所以不能被重写
13.6 泛型接口
好处:
泛型接口提供了出色的编译时类型安全性。
处理值类型时装箱次数会少很多。
类可以实现同一个接口若干次(每次使用不同的类型参数)。
13.7 泛型和接口约束
将泛型类型参数约束为接口的好处:
第一可将类型参数约束为多个接口。(传递的参数的类型必须实现全部接口约束)
第二是传递值类型的实例时减少装箱。
13.8 实现多个具有相同方法名称和签名的接口
要实现多个接口相同的方法,必须使用“显示接口方法实现”。
13.9 用显示接口方法实现来曾强编译时类型安全性
13.10 谨慎使用显示接口方法实现
EIMI主要问题:
没有文档解释类型具体如何实现一个EIMI方法,也没有Microsoft Visual Studio"智能感知"支持。
值类型的实例在转换成接口时装箱。
EIMI不能由派生类调用。
13.11 设计:基本类型
IS-A对比CAN-DO关系
类型只能继承一个实现。如果派生类型和基类型建立不起IS-A关系,就不用基类而用接口。接口意味着CAN-DO关系。如果多种对象都“能”做某事,就为它们创建接口。
易用性
对于开发人员,定义基类派生的新类型通常比实现接口的所有方法容易的多。基类型可提供大量功能,所以派生类型可能只需稍作改动。而提供接口的话,新类型必须实现所有成员。
一致性实现
无论接口协定订立的多好,都无法保证所有人百分之百正确实现它。如果为基类提供良好的默认实现,那么一开始得到的就是能正常工作并经过良好测试的类型。
版本控制
向基类型添加一个方法,派生类型将继承新方法。