第 17讲 抽象类
教学目的与要求:
了解抽象类的综合程序设计 。
掌握纯虚函数和抽象类 。
教学内容提要:
1,纯虚函数;
2,抽象类;
3,综合举例;
教学重点:纯虚函数与抽象类的声明和使用 。
教学难点:纯虚函数与抽象类的声明和使用 。
教学进度,P210~P217
教学过程:
17.1 纯虚函数
1,纯虚函数是一个在基类中说明的虚函数,它在该基类中没有定义具体的操作内容,要求各派生类根据实际需要定义自己的版本 。
2,纯虚函数的声明格式为:
virtual 函数类型 函数名 (参数表 )=0;
注意:
( 1),声明为纯虚函数之后,基类中就不再给出函数的实现部分 。
( 2),纯虚函数的函数体由派生类给出 。
( 3),在 C++中,还有一种情况是空的虚函数,空的虚函数是指函数体为空的虚函数,请注意它和纯虚函数的区别 。 纯虚函数根本就没有函数体,而空的虚函数的函数体为空 ( 如:
{ }),前者所在的类是抽象类,不能直接进行实例化 ( 不能定义对象 ),而后者所在的类是可以实例化的 。
例 17.1纯虚函数的使用 。
#include<iostream.h>
class Circle {
public:
void setr(int x){ r=x; }
virtual void show()=0; // 纯虚函数
protected:
int r;
};
class Area:public Circle{
public:
void show(){ cout<<"Area is "<<3.14*r*r<<endl;}
}; // 重定义虚函数 show( )
class Perimeter:public Circle{
public:
void show(){cout<<"Perimeter is "<<2*3.14*r<<endl;}
}; // 重定义虚函数 show( )
void main()
{
Circle *ptr;
Area ob1;
Perimeter ob2;
ob1.setr(10);
ob2.setr(10);
ptr=&ob1;
ptr->show();
ptr=&ob2;
ptr->show();
}
17.2 抽象类抽象类是一种特殊的类,它为一族类提供统一的操作界面 。
1,抽象类:带有纯虚函数的类
2,抽象类的特征:
( 1),抽象类不能实例化,即不能定义一个抽象类的对象主要作用是通过它为一个类族建立一个公共的接口,使它们能够更有效地发挥多态特征 。 而接口的完整实现 (即纯虚函数的函数体 ),要由派生类自己给出 。
( 2),抽象类派生出新的类之后,如果派生类给出所有纯虚函数的函数实现,这个派生类就可以定义自己的对象,因而不再是抽象类;反之,如果派生类没有给出全部纯虚函数的实现,还继承了部分纯虚函数,这时的派生类仍然是一个抽象类 。
例 17.2分析下列程序的运行结果例 17.3 定义一个 shape抽象类,在此基础上派生出 rectangle类和 circle类,二者都有 getarea( )函数计算对象的面积,
getperim( )函数计算对象的周长。
现假设某高校按如下方式确定教师工资:对于在某一学科取得突出成就的学术带头人聘为特聘教授,给予每月 10000元的津贴;对于其他有突出贡献的教学科研骨干聘为责任教授,给予每月 5000元的津贴。普通教学和科研人员则从其教学课时和科研经费中获得补助。特聘教授和责任教授原工资待遇不变。
该程序的类图如图所示综合实例程序如下:
注根据上述要求,可以声明基类为教师 (Teacher),该基类包含一些所有教师共有的数据比如教师的姓名、级别、编号、月工资;该基类的成员函数中计算工资、显示教师的基本信息可以考虑声明为纯虚函数,因为对于抽象的教师类来说,这些成员函数不具有实际意义。
【 17.3 综合实例 】
Teacher
int nNo;
char *cName;
GRADE eGrade;
double dblSalary;
Static int nCount;
Teacher();
~Teacher();
virtualvoidsetGrade(GRADE egrade=norProf){}
NorProf
double dblClassHour;
double dblHourPay;
NorProf () ;
void setGrade(GRADE);
void calSalary();
void dispMsg();
ResProf
double dblResMoney;
double dblPateFromRes;
ResProf () ;
void setGrade(GRADE);
void calSalary();
void dispMsg();
SpecProf
double dblMonSalary;
SpecProf () ;
void setGrade(GRADE);
void calSalary();
void dispMsg();
RespProf
double dblMonSalary;
RespProf () ;
void setGrade(GRADE);
void calSalary();
void dispMsg();
图 程序的类图
//EXAMPLE.H
//类的声明
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#define N 10000
typedef enum grade{specProf,respProf,norProf,resProf} GRADE;
//声明枚举类型,包括特聘教授、责任教授、教学人员和研究人员
class Teacher //声明抽象基类
{
protected:
int nNo; //编号
char *cName; //姓名
GRADE eGrade; //级别
double dblSalary; //工资
static int nCount; //教工总数
(续 )
public:
Teacher();
~ Teacher();
virtual void setGrade(GRADE egrade=norProf):eGrade(egrade){}
virtual void calSalary()=0; //纯虚函数,计算工资总数
virtual void dispMsg()=0; //纯虚函数,显示教工基本信息
};
class NorProf:virtual public Teacher //声明教学人员派生类
{
protected:
double dblClassHour; //每月授课课时数
double dblHourPay; //每课时补助
public:
NorProf();
void setGrade(GRADE);
void calSalary();
void dispMsg();
};
(续 )
class ResProf:virtual public Teacher //声明研究人员派生类
{
protected:
double dblResMoney; //每月承担的科研经费总数
double dblRateFromRes; //提成
public:
ResProf();
void setGrade(GRADE);
void calSalary();
void dispMsg();
};
class SpecProf:public NorProf,public ResProf
//声明特聘教授派生类,该类从教学人员和研究人员派生
{
private:
double dblMonSalary; //特聘教授的每月固定津贴
public:
SpecProf();
void setGrade(GRADE);
(续 )
void calSalary();
void dispMsg();
};
class RespProf:public NorProf,public ResProf
//声明责任教授派生类,该类从教学人员和研究人员派生
{
private:
double dblMonSalary; //责任教授每月固定津贴
public:
RespProf();
void setGrade(GRADE);
void calSalary();
void dispMsg();
};
//EXAMPLE.CPP
//类的实现
#include <iostream.h>
#include″ EXAMPLE.H″
(续 )
int Teacher::nCount=N;
Teacher::Teacher():dblSalary(800.0),eGrade(norProf)
{
char name[ 30] ;
cout<<″Input the name of the teacher:″;
cin>>name;
cName=new char[ strlen(name)+1] ;
strcpy(cName,name);
nCount++;
nNo=nCount;
}
Teacher::~ Teacher()
{
delete []cName;
}
SpecProf::SpecProf():dblMonSalary(10000.0)
{
dblHourPay=8.0;
dblRateFromRes=0.01;
(续 )
}
void SpecProf::setGrade(GRADE)
{
Teacher::setGrade(specProf);
}
void SpecProf::calSalary()
{
cout<<″Please input the classhours of one month for ″<<cName;
cin>>dblClassHour;
cout<<endl;
cout<<″Please input the research money of one month for ″<<cName;
cin>>dblResMoney;
cout<<endl;
//特聘教授工资包括基本工资 +津贴 +课时补助 +科研经费提成
dblSalary=dblSalary+dblMonSalary+dblHourPay*dblClassHour+
dblRateFromRes*dblResMoney;
cout<<cName<<″is a special Prof,His Salary is,″<<dblSalary
<<endl;
}
(续 )
void SpecProf::dispMsg()
{
cout<<″Special Prof,″<<cName<<″,his No,is:″<<nNo
<<″,his grade is,″<<eGrade<<″,his salary is:″
<<dblSalary<<endl;
cout<<″This is the basic message of ″<<cName<<endl;}
RespProf::RespProf():dblMonSalary(5000.0)
{
dblHourPay=8.0;
dblRateFromRes=0.01;
}
void RespProf::setGrade(GRADE)
{
Teacher::setGrade(respProf);
}
void RespProf::calSalary()
{
cout<<″Please input the classhours of one month for ″<<cName;
(续 )
cin>>dblClassHour;
cout<<endl;
cout<<″Please input the research money of one month for ″<<cName;
cin>>dblResMoney;
cout<<endl;
//责任教授工资包括基本工资 +津贴 +课时补助 +科研经费提成
dblSalary=dblSalary+dblMonSalary+dblHourPay*dblClassHour+
dblRateFromRes*dblResMoney;
cout<<cName<<″is a responsible Prof,His Salary is,″<<dblSalary
<<endl;
}
void RespProf::dispMsg()
{
cout<<″Responsible Prof,″<<cName<<″,his No,is:″<<nNo
<<″,his grade is,″<<eGrade<<″,his salary is:″
<<dblSalary<<endl;
cout<<″This is the basic message of ″<<cName<<endl;
}
(续 )
NorProf::NorProf():dblHourPay(8.0)
{}
void NorProf::setGrade(GRADE)
{
Teacher::setGrade(norProf);
}
void NorProf::calSalary()
{
cout<<″Please input the classhours of one month for ″<<cName;
cin>>dblClassHour;
//教学人员工资为基本工资 +课时补助
dblSalary=dblSalary+dblClassHour*dblHourPay;
cout<<cName<<″is a normal Prof and his salary is:″<<dblSalary
<<endl;
}
void NorProf::dispMsg()
{
(续 )
cout<<″Normal Prof,″<<cName<<″,his No,is:″<<nNo
<<″,his grade is,″<<eGrade<<″,his salary is:″
<<dblSalary<<endl;
cout<<″This is the basic message of ″<<cName<<endl;
}
ResProf::ResProf():dblRateFromRes(0.01)
{}
void ResProf::setGrade(GRADE)
{
Teacher::setGrade(resProf);
}
void ResProf::calSalary()
{
cout<<″Please input the research money of one month for ″<<cName;
cin>>dblResMoney;
//研究人员工资包括基本工资 +科研经费提成
dblSalary=dblSalary+dblRateFromRes*dblResMoney;
(续 )
cout<<cName<<″is a research Prof and his salary is:″<<dblSalary
<<endl;
}
void ResProf::dispMsg()
{
cout<<″Research Prof,″<<cName<<″,his No,is:″<<nNo
<<″,his grade is,″<<eGrade<<″,his salary is:″
<<dblSalary<<endl;
cout<<″This is the basic message of ″<<cName<<endl;
}
//EXAMPLE.CPP
//主程序
#include <iostream.h>
#include ″EXAMPLE.H″
void main()
{
SpecProf teacher1; //声明特聘教授对象
RespProf teacher2; //声明责任教授对象
NorProf teacher3; //声明教学人员对象
ResProf teacher4; //声明研究人员对象
Teacher *ptrTeacher; //声明抽象基类的指针
(续 )
ptrTeacher=&teacher1;
ptrTeacher->setGrade();
ptrTeacher->calSalary();
ptrTeacher->dispMsg();
ptrTeacher=&teacher2;
ptrTeacher->setGrade();
ptrTeacher->calSalary();
ptrTeacher->dispMsg();
ptrTeacher=&teacher3;
ptrTeacher->setGrade();
ptrTeacher->calSalary();
ptrTeacher->dispMsg();
ptrTeacher=&teacher4;
ptrTeacher->setGrade();
ptrTeacher->calSalary();
ptrTeacher->dispMsg();
}
(续 )
Input the name of the teacher,XXXXX
Input the name of the teacher,YYYYY
Input the name of the teacher,ZZZZZ
Input the name of the teacher,WWWW
Please input the classhours of one month for XXXXX 60
Please input the research money of one month for XXXXX50000
XXXXX is a special Prof,His salary is,11780
Special Prof,XXXXX,his No,is,10001,his grade is,2,his salary is,11780
This is the basic message of XXXXX
Please input the classhours of one month for YYYYY60
Please input the research money of one month for YYYYY50000
YYYYY is a responsible Prof,His salary is,6780
Responsible Prof,YYYYY,his No,is,10002,his grade is,2,his salary is,6780
This is the basic message of YYYYY
Please input the classhours of one month for ZZZZZ60
ZZZZZ is a normal Prof,and his salary is,1280
Normal Prof,ZZZZZ,his No,is,10003,his grade is,2,his salary is,1280
This is the basic message of ZZZZZ
Please input the research money of one month for WWWWW50000
WWWWW is a research Prof,and his salary is,1300
Research Prof,WWWWW,his No,is,10004,his grade is,2,his salary is,1300
This is the basic message of WWWWW
(续 )
小结
1、什么是纯虚函数
2、抽象类的特征及作用
3、综合程序设计作业:
P221 5.17