第四章 继 承
第3章介绍了如何使用C#中的各个类,其重点是如何定义方法、构造函数、属性和单个类(或单个结构)中的其他成员。我们指出,所有的类最终都派生于 System.Object类,但并没有说明如何创建继承类的层次结构。继承是本章的主题。我们将简要讨论C#对继承的支持,然后详细论述如何在C#中编 码实现(implementation)继承和接口继承。注意,本章假定您已经熟悉了继承的基本概念,包括虚函数和重写。我们将重点阐述用于提供继承的语 法和与继承相关的主题,例如虚函数,C#继承模型的其他方面是C#所特有的,其他面向对象的语言都不具备。
4.1 继承的类型
首先介绍C#在继承方面支持和不支持的功能。
4.1.1 实现继承和接口继承
在面向对象的编程中,有两种截然不同的继承类型:实现继承和接口继承。
● 实现继承:表示一个类型派生于一个基类型,拥有该基类型的所有成员字段和函数。在实现继承中,派生类型的每个函数采用基类型的实现代码,除非在 派生类型的定义中指定重写该函数的实现代码。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承是非常有效的。例如 第28章讨论的Windows Forms类。第28章也讨论了基类System.Windows.Forms.Control,该类提供了常用Windows控件的非常复杂的实现代 码,第28章还讨论了许多其他的类,例如System. Windows.Forms.TextBox和System.Windows.Forms.ListBox,这两个类派生于Control,并重写了函 数,或提供了新的函数,以实现特定类型的控件。
● 接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。例如,某 些类型可以指定从接口System.IDisposable(详见第11章)中派生,从而提供一种清理资源的方法Dispose()。由于某种类型清理资 源的方式可能与另一种类型的完全不同,所以定义通用的实现代码是没有意义的,此时就适合使用接口继承。接口继承常常被看做提供了一种契约:让类型派生于接 口,来保证为客户提供某个功能。
在传统上,像C++这样的语言在实现继承方面的功能非常强大。实际上,实现继承是C++编程模型的核心。另一方面,VB6不支持类的任何实现继承, 但因其底层的COM基础体系,所以它支持接口继承。
在C#中,既有实现继承,也有接口继承。它们没有强弱之分,因为这两种继承都完全内置于语言中,因此很容易为不同的情形选择最好的体系结构。