多态的概念:
????????调用同一个函数名,传入不同的参数,会执行不同的函数体
多态理解
对于多态的理解,在我第一次看到多态的概念时首先想到的是c++中函数的重载,功能类似,函数名相同,参数不同(个数和类型),与返回值无关,这样的函数就互为重载
而多态是建立在重写的基础之上的,是类与类之间的关系,是发生在不同的类之间的,子类重写父类的方法。 实现不同的子类,不同的实现形态。 而重载是类的内部的方法构型上的不同,是发生在同一个类里面的,其作用域不同
静态多态和动态多态:
在首先提到这两个名称时想到的是之前学习c语言时学到的静态库与动态库
静态库的静态链接:是编译时将静态库加载到可执行文件中
动态库的动态链接:是运行时才会将标记的动态库加载到可执行文件中
静态多态和动态多态这点和静态链接与动态链接相同,都是链接的时刻不同
静态多态(函数调用和函数体绑定早):调用一个函数,在编译阶段就能够确定最终执行
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?的是哪个函数体
动态多台(函数调用和函数体绑定晚):调用一个函数,在运行阶段才能确定最终执行的
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?是哪个函数体
?如图:由于c++的g++对函数的重命名,在链接时就已绑定函数体进行调用了
动态多态例子:
如下,这是一个计算形状面积的动态多态例子
#include <iostream>
using namespace std;
//形状类:求面积 属性:面积
//圆类 求面积 属性:半径 面积
//矩形类 求面积 属性:宽 高 面积
class Shape
{
public:
Shape()
{
s = 0;
cout << "Shape()" << endl;
}
~Shape()
{
cout << "~Shape()" << endl;
}
virtual float getArea()
{
cout << "Shape getArea" << endl;
return s;
}
protected:
float s; //面积
};
class Circle :public Shape
{
public:
Circle(float _r = 10)
{
r = _r;
cout << "Circle(float)" << endl;
}
~Circle()
{
cout << "~Circle()" << endl;
}
virtual float getArea()
{
cout << "Circle getArea" << endl;
s = 3.14 * r * r;
return s;
}
private:
float r; //半径
};
class Rectangle :public Shape
{
public:
Rectangle(float _w = 5, float _h = 5)
{
w = _w;
h = _h;
cout << "Rectangle(float)" << endl;
}
~Rectangle()
{
cout << "~Rectangle()" << endl;
}
virtual float getArea()
{
cout << "Rectangle getArea" << endl;
s = w * h;
return s;
}
private:
float w; //宽
float h; //高
};
void calArea(Circle *shape)
{
cout << "面积是:" << shape->getArea() << endl;
}
int main()
{
//调用同一个函数,传入不同的形状对象,执行不同的计算面积的函数
Circle circle;
calArea(&circle);
Rectangle rect;
calArea(&rect);
return 0;
}
?如上图在类外定义一个父类指针,在调用时让其指向子类对象,就可以访问子类从父类继承过来的成员
动态多台实现条件
- 继承,多个子类一个父类
- 父类有虚函数,子类重写父类的虚函数
- 父类指针指向子类对象(一个函数,函数的形参是父类的指针,实参是子类对象的地址)
重写:子类定义了和父类一模一样(函数名、参数、返回值)的虚函数
|