一个操作随着所传递或捆绑的对象类型的不同能够做出不同的反应,其行为模式称为多态。
下面的例子中,通过对象类型不同来区分不同的类,实现多态。
要求类层次中的父类有一个反映类型的数据成员,而且该成员要能够被使用者所访问(要求是public)。
//-----------student.h--------------
#ifndef STUDENT__H
#define STUDENT__H
#include <iostream>
class Student
{
private:
std::string name;
int semesterHours;
double average;
public:
enum StudentType{STUDENT,GRADUATESTUDENT}; //定义反应类型的的数据成员,通过这里来区分 是Student的对象还是GraduateStudent的对象
StudentType type;
Student(std::string pN = "noName")
{
type = STUDENT; //Student对象的标志
name = pN;
semesterHours = 0;
average = 0;
}
void calcTuition(){std::cout<<"Student tuition calculation."<<std::endl;}
};
#endif
//----------graduatestudent.h----------
#ifndef GRADUATESTUDENT__H
#define GRADUATESTUDENT__H
#include "student.h"
class Advisor
{
private:
int noOfMeeting;
};
class GraduateStudent : public Student //继承 Student
{
private:
Advisor advisor;
int qualifierGrade;
public:
GraduateStudent(std::string pN = "noName")
{
type = GRADUATESTUDENT; //GraduateStudent 对象的标志
qualifierGrade = 0;
Student::Student(pN); //父类重载 传递 name
}
void calcTuition(){std::cout<<"GraduateStudent Tuition calculation."<<std::endl;}
};
#endif
//---------main.cpp------------
#include "student.h"
#include "graduatestudent.h"
using namespace std;
void fn(Student &s)
{
switch(s.type)
{
case Student::STUDENT: //通过构造函数中的type来区分对象的类型
s.calcTuition();
break;
case GraduateStudent::GRADUATESTUDENT: //通过构造函数中的type来区分对象的类型
GraduateStudent &ss = static_cast<GraduateStudent &>(s); //这个地方用的 “很妙”
ss.calcTuition();
//(static_cast<GraduateStudent>s).calcTuition(); //错
//GraduateStudent(s).calcTuition(); //错
break;
}
}
int main(int argc,char **argv)
{
Student ds("Lo lee undergrade");
GraduateStudent gs("Jack");
fn(ds); //通过对象类型做出不同反应
fn(gs); //通过对象类型做出不同反应
return 0;
}
Student tuition calculation.
GraduateStudent Tuition calculation.
请按任意键继续. . .
在父类中设置type成员(student.h中)是为了让所有的子类都能共享。
通过这样的手段,我们终于可以让函数fn()实现多态了,也就是fn()函数代码可以通过对象的公有数据数据成员辨认其类的层次信息,从而选择决定调用哪个成员函数。
1