多态(C++语言实现)

C++中的多态是非常重要的一个概念。也是比较难理解的一个方面。***从字面意思理解,多态就是多种形态。***这也是非常常见的一种说法。

1.多态的引出

如下图所示,我们需要解决的问题就是计算几何图形的面积,然后定义了一个类Shape,但是在具体实现的时候,各个图形的面积计算方法是不同的。
在这里插入图片描述
于是我们定义了不同的子类(图形),然后根据图形写出了面积的计算方法的代码:

#include <iostream> 
using namespace std;

class Shape {
protected:
	int width, height;
public:
	Shape(int a = 0, int b = 0)
	{
		width = a;
		height = b;
	}
	int area()
	{
		cout << "Parent class area :" << endl;
		return 0;
	}
};
class Rectangle : public Shape {
public:
	Rectangle(int a = 0, int b = 0) :Shape(a, b) { }
	int area()
	{
		cout << "Rectangle class area :" << endl;
		return (width * height);
	}
};
class Triangle : public Shape {
public:
	Triangle(int a = 0, int b = 0) :Shape(a, b) { }
	int area()
	{
		cout << "Triangle class area :" << endl;
		return (width * height / 2);
	}
};
// 程序的主函数
int main()
{
	Shape *shape;
	Rectangle rec(10, 7);
	Triangle  tri(10, 5);

	// 存储矩形的地址
	shape = &rec;
	// 调用矩形的求面积函数 area
	//shape->area();
	printf("\t---%d---\n", shape->area());
	// 存储三角形的地址
	shape = &tri;
	// 调用三角形的求面积函数 area
	//shape->area();
	printf("\t---%d---\n", shape->area());
	system("pause");
	return 0;
}

然而我们执行代码之后出现了如下的结果:
在这里插入图片描述
这是因为我们子类继承了父类的各种属性和方法,而在父类中area方法的返回值是0,因为调用函数 area() 被编译器设置为父类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定

2.虚函数

要实现我们理想的状态,就需要用到虚函数,也就是在父类的area方法前面加上virtual关键字,代码如下:

#include <iostream> 
using namespace std;

class Shape {
protected:
	int width, height;
public:
	Shape(int a = 0, int b = 0)
	{
		width = a;
		height = b;
	}
	virtual int area()
	{
		cout << "Parent class area :" << endl;
		return 0;
	}
};
class Rectangle : public Shape {
public:
	Rectangle(int a = 0, int b = 0) :Shape(a, b) { }
	int area()
	{
		cout << "Rectangle class area :" << endl;
		return (width * height);
	}
};
class Triangle : public Shape {
public:
	Triangle(int a = 0, int b = 0) :Shape(a, b) { }
	int area()
	{
		cout << "Triangle class area :" << endl;
		return (width * height / 2);
	}
};
// 程序的主函数
int main()
{
	Shape *shape;
	Rectangle rec(10, 7);
	Triangle  tri(10, 5);

	// 存储矩形的地址
	shape = &rec;
	// 调用矩形的求面积函数 area
	//shape->area();
	printf("\t---%d---\n", shape->area());
	// 存储三角形的地址
	shape = &tri;
	// 调用三角形的求面积函数 area
	//shape->area();
	printf("\t---%d---\n", shape->area());
	system("pause");
	return 0;
}

运行结果为:
在这里插入图片描述
这就是多态的一般使用方式。有了多态,大大方便了我们代码的扩展。这种操作被称为动态链接,或后期绑定

从这个例子就可以看出来,多态可以更加方便我们去根据不同的对象实现不同的方法,量体裁衣。

3.纯虚函数

从上面一个例子可以看出,父类的虚函数在每个子类中都做了实现,那就说明父类的虚函数并没有十分重要,那我们可不可以有一种更加简单的实现方式呢?

答案是有,就是纯虚函数。写法如下:

class Shape {
protected:
	int width, height;
public:
	Shape(int a = 0, int b = 0)
	{
		width = a;
		height = b;
	}
	virtual int area() = 0;
};

理解起来也十分方便,就是令其为零,但是这个时候父类就变成了抽象类,抽象类是不能实例化的,通常用于实现接口的定理。比方说:

int main()
{
	Shape shape(10,20);
	printf("宽度为:%d\n",shape.width);
	system("pause");
	return 0;
}

这个时候程序就会报错,提示:
在这里插入图片描述

4.拓展

从最基本的逻辑来说,如果父类定义了纯虚函数,如果子类不实现父类的纯虚函数,肯定是不行的。但是如果子类不实现父类的虚函数,情况又会如何呢?

答案是:会和我们的第一版代码一样,执行的时候返回0

-------------------------------------------------------------------------------------END------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值