多态分为两种:通用的多态(universal)和特定的多态(ad hoc)。前者用来系统地刻画语义上相关的一组类型。;后者用来刻画语义上无关联的类型间的关系。
通用的多态又分为参数多态(parametric)和包含多态(inclusion);特定的多态分为过载多
态(重载多态)(overloading)和强制多态(coercion)。
包含多态,是指通过子类型化,一个程序段既能处理类型T的对象,也能够处理类型T的子类型S的对象。在C++中公有继承关系是一种包含多态,每一个类可以直接公有继承自父类或多个父类,如语句class Dpublic P1,public P2{……};表示类D分别是类P1和类P2的子类型。
参数多态,与类属(类模板)相关联,类属是一个可以参数化的模板, 其中包含的操作所涉及的类型必须用类型参数实例化。这样,由类模板实例化的各类都具有相同的操作,而操作对象的类型却各不相同。
过载多态(重载多态),是多态性的最简形式,而且把更大的灵活性和扩展性添加到程序设计语言中,它分成操作符重载和函数重载。这个是我们一般比较理解的多态,也是用得比较多的。
强制多态,强制也称类型转换。C++语言定义了基本数据类型之间的转换规则,即:char->short->int->unsigned->long->unsigned long->float->double->long double
赋值操作是个特例,上述原则不再适用。当赋值操作符的右操作数的类型与左操作数的类型不同时,右操作数的值被转换为左操作数的类型的值,然后将转换后的值赋值给左操作数。
程序员可以在表达式中使用3种强制类型转换表达式:①static_cast<T>(E);②T(E);③(T)E。其中任意一种都可改变编译器所使 用的规则,以便按自己的意愿进行所需的类型强制。其中E 代表一个运算表达式,T代表一个类型表达式。第三种表达形式是C语言中所使用的风格,在C++中,建议不要再使用这种形式,应选择使用第一种形式。例如, 设对象f的类型为double,且其值为3.14。则表达式static_cast<int>(f)的值为3,类型为int。
通过构造函数进行类类型与其它数据类型之间的转换必须有一个前提,那就是此类一定要有一个只带1个非缺省参数的构造函数,通过构造函数进行类类型的转换只能从参数类型向类类型转换,而想将一个类类型向其它类型转换是办不到的。类类型转换函数就是专门用来将类类型向其它本类型转换的,它是一种类似显式类型转 换的机制。转换函数的设计有以下几点要特别注意:①转换函数必须是类的成员函数;②转换函数不可以指定其返回值类型;③转换函数其参数行不可以有任何参数。
强制使类型检查复杂化,尤其在允许重载的情况下,导致无法消解的二义性,在程序设计时要注意避免由于强制带来的二义性。
其他类型的多态
现在的多数文献中都认为,在面向对象程序设计语言中还存在着两种多态:
·在有继承关系的类之间存在的多态(但不能完全等同于包含多态);
·通过动态绑定机制,在运行时才确定接受消息的对象类型(如c++语言中的虚拟函数)。