前两篇中,我们分别介绍了面向对象的封装和继承两个特性,今天我们来说最后一个特性:多态。
什么是多态
用一句话来概括多态:允许父类的指针指向子类对象。
为什么要用父类的指针去指向子类对象呢?我们想象一个最简单的场景,如果我们需要一个函数的参数是可变数据类型,那如何实现呢?C++是不允许模糊数据类型存在的,这个需求听起来几乎不可能实现。不过有了多态,我们可以把参数类型设置为父类的指针类型,这样在参数传递的时候我们就可以传递这个父类的任意一个子类的对象了。听起来比较乱,我们用一个例子来解释。
先看看下面这段代码:
#include <iostream>using namespace std;class Animal
运行结果:
先看Functions()函数,它的参数是一个Animal类指针,Animal是一个抽象类,派生了两个子类:Dog和Cat。在main函数中,我们可以很方便地把这两个子类的对象传给Animal指针。这就是多态。
多态的背后隐藏着伟大的设计模式思想,希望大家慢慢体会。
抽象类
Animal是个抽象类。它的特点是:
包含虚函数
不能实例化
为什么要用抽象类呢?它的意义仅仅是定义成员函数的外观。在这个例子中,我们定义了两个虚函数:Run()和Cry()。有了这样一个抽象类,我们才能保证Dog和Cat两个子类都拥有一模一样的两个成员函数。否则,Functions()函数就没法正常工作了。
星空问题的新需求
回到星空那段代码,假如我们这个项目需要A,B,C,三个人同时开发。A开发点状星星,B开发矩形的星星,C开发X形的星星。我们要确保三个人能同时开发,完成后能很容易的把三份代码加入项目中,该怎么办呢?
先分析一下代码:
class Star{public:
Star类中,影响星星形状的成员函数是Draw()和Remove(),我们可以利用多态把这两个函数抽象出来成为一个抽象类,之后让A,B,C三个人分别实现一个子类,这样就OK了。
来看看代码吧:
#include <graphics.h>#include <time.h>#include <conio.h>#define SCREEN_WIDTH 1024#define SCREEN_HEIGHT 768#define MAXSTAR 400class StarType
效果如下:
程序中,我们定义了一个抽象类StarType,之后三个类分别派生与这个抽象类。
我们重载了Star类的Init()方法,当我们要实现不同样子的星星时,就把相应的对象地址通过Init()方法传给Star类保存在m_pStarType属性中。当执行Move函数时,就会通过这个属性调用不同的方法来完成。是不是很神奇呢?
这其实是一种设计模式,假如我们有一天需要再多加几种星星,只需要再多实现几个StarType的派生类就行了,其他代码几乎不用改变。
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入学习交流群
639368839,我们一起学C/C++!
还没有评论,来说两句吧...