4. C++多态
1. 概念认知
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内幕”)。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。多态性在Object Pascal和C++中都是通过虚函数实现的。 --百度百科
由以上解释大致可以了解到多态的含义。对于C++来说,多态是就是同一个函数不同的执行效果。实现方式就是子类根据自身需要更改了从父类继承的方法。
2. 基本语法
C++支持多种多态,从实现形式上概括,有虚函数、重载等。从绑定时间,分为静态多态和动态多态,又称为编译期多态和运行期多态。
简单地来讲:静态多态是指在编译后就已经绑定,主要实现形式有函数模板和类方法重载;动态多态是指在运行期间才能确定,主要实现形式为基类的虚函数继承。
静态多态(重载):
#include <iostream>
using namespace std;
/* 类重载实现多态 */
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
/* 函数重载实现多态 */
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double i) {
cout << "浮点数为: " << i << endl;
}
void print(char str[]) {
cout << "字符串为: " << str << endl;
}
int main(void)
{
printData pd;
// 输出整数
cout << "类重载方式: " << endl;
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
cout << endl <<"函数重载方式: " << endl;
print(5);
print(3.141);
print((char *)"Hello world");
return 0;
}
输出结果:
类重载方式:
整数为: 5
浮点数为: 500.263
字符串为: Hello C++
函数重载方式:
整数为: 5
浮点数为: 3.141
字符串为: Hello world
动态多态(继承):
#include <iostream>
using namespace std;
class Parent {
public:
virtual void print() {
cout << "this is Parent" << endl;
}
};
class Child_1: public Parent {
public:
void print() {
cout << "this is Child_1" << endl;
}
};
class Child_2: public Parent {
public:
void print() {
cout << "this is Child_2" << endl;
}
};
int main()
{
Child_1 m;
Child_2 n;
m.print();
n.print();
return 0;
}
结果输出:
this is Child_1
this is Child_2
小结:
从上述的两个例子可以发现,静态多态是通过重载方式来实现的;动态方式则是通过继承和虚函数来实现。当函数有virtual声明时,就成为虚函数,其作用类似于备胎,当作用域有同名函数时,会执行同名函数不执行虚函数,否则会执行虚函数。
3 拓展延伸
问题: 利用多态实现正方形与圆形的面积计算。
要求1. 实现基类,内部成员包括显示类类元素方法、显示面积方法、面积计算方法
要求2. 实现两个子类Square、Circle,实现多态功能。
标准答案:
#include<iostream>
using namespace std;
const double PI = 3.14; //基类
class Shape
{
public:
virtual void show() = 0; //显示各类基本元素
virtual void showArea() = 0; //显示面积
virtual void Caculate() = 0; //面积算法
~Shape(){ }
};
//正方形
class Square : public Shape
{
public:
Square()
{
Lenth = 0;
Width = 0;
}
Square(double lenth, double width)
{
Lenth = lenth;
Width = width;
}
virtual void show()
{
cout << "Lenth:" << Lenth << " Width" << Width << endl;
}
virtual void showArea()
{
cout << "SquareArea:" << SquareArea << endl;
}
virtual void Caculate()
{
SquareArea = Lenth * Width;
}
private:
double Lenth;
double Width;
double SquareArea;
};
//圆形
class Circle : public Shape
{
public:
Circle(){ Radius = 0; }
Circle(double radius)
{
Radius = radius;
}
virtual void show()
{
cout << "半径:" << Radius << endl;
}
virtual void showArea()
{
cout << "CircleArea" << CircleArea << endl;
}
virtual void Caculate()
{
CircleArea = PI * Radius * Radius;
}
private:
double Radius;
double CircleArea;
};
void print(Shape& sp)
{
sp.Caculate();
sp.show();
sp.showArea();
}
int main()
{
Square sq1(5, 4);
Circle cr1(7);
Square sq2;
print(sq1);
print(cr1);
print(sq2);
return 0;
}
结果输出:
Lenth:5 Width4
SquareArea:20
半径:7
CircleArea153.86
Lenth:0 Width0
SquareArea:0
小结
在子成员中定义自己需要的整型成员,并在构造函数中实现成员初始化。
4. 归纳总结
主要介绍C++静态多态与动态多态的区别,结合实际的场景例子加深对多态的理解。