问答题 【程序说明】 对于一个公司的雇员来说,无非有3种:普通雇员、管理人员和主管。这些雇员有共同的数据:名字、每小时的工资,也有一些共同的操作:数据成员初始化、读雇员的数据成员及计算雇员的工资。但是,他们也有不同。例如.管理人员除有这些共同的特征外,有可能付固定薪水,主管除有管理人员的共同特征外,还有其他物质奖励等。3种雇员中,管理人员可以看作普通雇员的一种,而主管又可以看作管理人员的一种。我们很容易想到使用类继承来实现这个问题:普通雇员作为基类,管理人员类从普通雇员类中派生,而主管人员类又从管理人员类中派生。 下面的程序1完成上述各个类的定义,并建立了3个雇员(一个普通雇员、一个管理人员和一个主管)的档案,并打印出各自的工资表。将“程序1”中的成员函数定义为内联函数,pay成员函数定义为虚函数,重新完成上述要求。 【程序1】 //普通雇员类 class Employee { public: Employee(char*theName,float thePayRate); char * getName()const; float getPayRate()const; float pay(float hoursWorked)const: protected: char*name; //雇员名称 float payRate; //薪水等级 }; Employee::Employee(char * theName,float thePayRate) { name=theName; payRate=thePayRate; } char*Employee::getName()const { return name; } float Employee::getPayRate()const } return payRate; } float Employee::pay(float hoursWorked)const { return hoursWorked * payRate; } //管理人员类 Class Manager:public Employee { public: //isSalaried付薪方式:true付薪固定工资,false按小时付薪 Manager(char * theName,float thePayRate,bool isSalaried); bool getSalaried()const; float pay(float hoursWorked)const; protected: bool Salaried; }; Manager::Manager(Char*theName,float thePayRate,bool isSalaried) :Employee(theName,thePayRate) { salaried=isSalaried; } bool Manager::getSalaried() const { return Salaried; } float Manager::pay(float hoursWorked)const { if(salaried) return payRate; /*else*/ return Employee::pay(hoursWorked); } //主管人员类 class Supervisor:public Employee { public: Supervisor(Char*theName,float thePayRate,float theBouns): Employee(theName,thePayRate,{{U}} (1) {{/U}}),bouns(theBouns){} float getBouns()const{return bouns;} float pay(float hoursWorked)const return{{U}} (2) {{/U}} } protected: float bouns; } #include" iostream.h" void main() { Employee e("Jack",50.00); Manager m("Tom",8000.00, true); Supervior s("Tanya",8000.00,8000.00); cout<<"Name:" <<e.getName()<<endl; cout<<"Pay:"<<e.pay(80)<<endl; //设每月工作80小时 tout<<"Nabe:" <<m.getName()<<end,; cout<<"Pay:" <<m.pay(40)<<endl; cout<<"Nabe:" <<s.getName()<<endl; cout<<"Pay:"<<s.pay(40)<<endl; //参数40在这里不起作用 } 【程序2】 #include "employee.h" //普通雇员类 class Employee { public: //构造函数 Employee(String theName,float thePayRate): name(theNabe),payRate(thePayRate){} //取雇员姓名 String getNabe() const{returnname;} //取雇员薪水等级 float getPayRate()const{return payRate;} //计算雇员薪水 virtual float pay(float hoursWorked)const {return{{U}} (3) {{/U}};} protected: String name; //雇员名称 float payRate; //薪水等级 }; //管理人员类 //继承普通雇员类 class Manager:public Employee { public: //构造函数 //isSalaried标识管理人员类的付薪方式 //true按阶段付薪(固定工资) //false按小时付薪 Manager(String theName,float thePayRate,bool isSalaned): Employee(theName,thePayRate),Salaried(isSalarled){} //取付薪方式 bool getSalarled()const{return salaried;} //计算薪水 virtual float pay(float{{U}} (4) {{/U}})const; protected: bool Salaried; }; float Manager::pay(float hoursWorked)const { if(salaried) //固定付薪方式 return payRate; else //按小时付薪 return{{U}} (5) {{/U}};} //主管人员类 class Supervisor:{{U}} (6) {{/U}} { public: //构造函数 Supervisor(String theName,float thePayRate,float theBouns): Manager(theName,thePayRate,true),bouns(theBouns){} //取奖金数额 float getBouns()const{return bouns;} //计算薪水 virtual float pay(float hoursWorked)const { retum payRate+bouns; } {{U}} (7) {{/U}} float bouns; } #include "employee.h" #include"jostream.h" void main() { {{U}} (8) {{/U}}* ep[3]; ep[0]=new Employee("Jack","50.00"); ep[1]=Flew Manager("Tom","8000.00",true); ep[2]=new Superwor("Tanya","8000.00","8000.00"); for(int i=0;i<3;i++){ cout<<"Name:"<<{{U}} (9) {{/U}}<<endl; cout<<"Pay:"<<{{U}} (10) {{/U}}<<endl; //设每月工作80小时 } }
【正确答案】
【答案解析】(1)true (2)payRate+bouns (3)hoursWorked*payRate (4)hoursWorked (5)hoursWorked*payRate (6)public Manager (7)protected: (8)Employee (9)ep[i]->getName() (10)ep[i]->pay(80) [解析] (1)普通雇员类是所有类的基类,描述了雇员的一些基本信息,管理人员类从普通雇员类中派生,管理人员的付薪方式与普通雇员可能相同,所以该类添加了一个成员变量标识,并覆盖了基类的pay ()函数。主管类从管理人员类中派生,主管人员是管理人员的一种,他们不仅支付固定薪水,而且还有奖金。所以在主管类中添加了bonus成员,保存他们的奖金数额,并覆盖了管理人员类的pay()函数重新计算工资。 (2)程序中建立了3个雇员(一个普通雇员、一个管理人员和一个主管)的档案,并打印出各自的工资表。事实上,将3种雇员分开处理会很繁琐,如果能够把他们看作同一种类型,都看成雇员类(他们本来都是雇员)统一处理,但在计算工资时再调用各自的Pay()函数,那程序会简单得多。这就需要利用多态特性,只要将Pay()函数定义成虚函数,便可以实现了。