原文转自 https://www.cnblogs.com/Dr-wei/p/11847942.html
类的多态和多态性
很多人喜欢将多态与多态性二者混为一谈,然后百思不得其解,其实只要分开看,就会很明朗。
一、多态
多态指的是一类事物有多种形态,(一个抽象类有多个子类,因而多态的概念依赖于继承)
- 序列数据类型有多种形态:字符串,列表,元组
- 动物有多种形态:人,狗,猪
- 文件有多种形态:文件、文本文件、可执行文件
二、多态性
注意:多态与多态性是两种概念
多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
多态性是一个接口(函数func)的多种实现(如obj.run(),obj.talk(),obj.click(),len(obj))
三、多态性的好处
- 增加了程序的灵活性:以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)
- 增加了程序额可扩展性:通过继承Animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用
四、小结
- 多态:同一种事物的多种形态,动物分为人类,猪类(在定义角度)
- 多态性:一种调用方式,不同的执行效果(多态性)
五、函数的多态性
多态性不只限于类中,对函数也是一样的,具体来讲就是函数名相同但是具体实现不同,这也叫重载。那么在返回值类型相同的情况下,重载是凭什么区别的?凭两点:1、函数参数个数,2、函数参数类型。这一种是经常能够用到的,也是推荐使用的。
C++也允许你的重载函数返回值不同,不过这必须满足重载函数的新参列表也必须不同才行。
C++中重载函数你最好不要只写一个形参类型,还应该再带上一个形参,因为这样做,因为编译器会对函数原型中的形参进行加密,而你不写形参的话,不同的编译器所采取的加密策略也不同,而你形参列表写得越模糊编译器所建立的可选集也就越多,这无疑会增加成本和复杂度。
多态指的就是用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。
面向对象的多态性可以分为4类:重载多态,强制多态,包含多态,参数多态。前面两种统称专用多态,后面两种统称通用多态。
1、重载多态
普通函数重载举例:
int add(int x, int y) {
return x + y;
}
double add(double x, double y) {
return x + y;
}
float add(float x, float y) {
return x + y;
}
重载多态包括前面的普通函数及类的成员函数的重载还有运算符的重载。
2、强制多态,是指将一个变元的类型加以变化,以符合一个函数或者操作的要求,举一个简单例子就清楚啦。
int a=1;
float b=2.4f;
float re=a+b;
这里的加法运算符在进行浮点数和整形数相加时,首先进行类型强制转换,把整形数变为浮点数再相加的情况就是强制多态的实例。
3,包含多态
指的是类族中定义于不同类中的同名函数的多态的行为,主要是通过虚函数来实现。
那么什么是虚函数呢?
虚函数:
在类的成员函数前加virtual关键字。虚函数是实现包含多态的基础。这里需要说明的是当基类里有虚函数且派生类中重新声明了和基类虚函数相同的函数,那么派生类该函数也是虚函数,这个过程称为对基类虚函数进行重写,这对于实现包含多态有重要意义。
包含多态的条件:
基类中必须包含虚函数,并且派生类中一定要对基类中的虚函数进行重写override。
通过基类对象的指针或者引用调用虚函数。
纯虚函数与抽象类:
纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要给出各自的定义。纯虚函数的声明格式为:
virtual 函数类型 函数名 (参数表)=0;
而抽象类就是指带有纯虚函数的类。
4,参数多态
采用函数模板,它可以用来创建一个通用的函数,以支持多种不同形参,避免重载函数的函数体重复设计,通过给出不同的类型参数,使得一个结构有多种类型。以实现参数多态。
定义的一般形式:
template <模板参数表>
函数返回值类型 函数名(参数表)
{
函数体
}
简单来说:多态性就是适当的使用接口函数,通过一个接口来使用多种方法,(相当于上级说一个命令,甲乙丙丁等人都做出反应,一个命令,产生多个反应。