实验七 继承与派生
【实验目的】
1、理解继承在面向对象程序设计中的重要作用;
2、理解继承和派生的概念;
3、掌握通过继承派生出一个新类的方法;
4、进一步学习简单面向对象程序的编写;
【实验内容】
1. 设计一个Person类,它有两个派生类Student和Employee,Employee有两个派生类Faculty和Staff。
•Person类有一个string类型的名字name,string型的身份号id,string型的电话号码phonenumber, Person类构造函数的对应name的参数不能有默认形参值。
•Student类有一个年级grade属性(Freshman、Sophomore、Junior或Senior),将属性值定义为常量;
•Employee类有一个string型的办公地点office,一个double型的月薪水salary和一个MyDate型的雇佣日期dateHired;
•Faculty类有一个级别rank属性(Professor = 3、 AssociateProfessor = 2、AssistantProfessor = 1),属性值也定义成常量。教师的薪水的计算方式为“薪水=基本工资×级别”;
•Staff类有一个职务position属性,为string类型,教工的薪水计算方式为“薪水=基本工资+津贴×工作年数”。工作年数算到2010年1月1日为止,基本工资BasicWages、津贴Allowance定义为常量。
•上述5个类都有一个print成员函数来输出该类对象除薪水外的基本信息。
•MyDate类有year、month、day三个数据成员,有一个计算两个MyDate对象间年差的成员函数diffYear(MyDate &),年差计算只精确到月;三个数据成员的获取器函数。
3. 定义上述类,并合理地补充构造函数和其它需要的函数。
在main函数中,定义一个Person类对象,一个Student类对象和一个Employee类对象一个Faculty类对象和一个Staff类对象。输出Person类及其派生类对象的基本信息,并输出Faculty类对象和Staff类对象的薪水。
1 #include<iostream> 2 #include<string> 3 const float BasicWages=4000; 4 const float Allowance=1000; 5 using namespace std; 6 class MyDate 7 {public: 8 MyDate(int y=0,int m=0,int d=0){ year=y;month=m;day=d;} 9 float diffYear(){ 10 MyDate in(2010,1,1); 11 return 2010-in.GETY()-in.GETM()/12.0;} 12 int GETY(){ return year;} 13 int GETM(){ return month;} 14 int GETD(){ return day;} 15 private: 16 int year,month,day; 17 }; 18 class Person 19 {public: 20 Person(string na,string i,string phonenum) 21 { name=na;id=i;phonenumber=phonenum;} 22 void print(){ cout<<"name: "<<name<<" id: "<<id<<" phonenumber: "<<phonenumber<<endl;} 23 protected: 24 string name,id,phonenumber; 25 }; 26 class Student:public Person 27 {public: 28 Student(string na,string i,string phonenum,string gra):Person(na,i,phonenum) 29 { grade=gra;} 30 void print(){ cout<<"name: "<<name<<" id: "<<id<<" phonenumber: "<<phonenumber<<" grade: "<<grade<<endl;} 31 private: 32 string grade; 33 }; 34 class Employee:public Person 35 {public: 36 Employee(string na,string i,string phonenum,string off):Person(na,i,phonenum) 37 {office=off;} 38 void print(){ cout<<"name: "<<name<<" id: "<<id<<" phonenumber: "<<phonenumber<<" office: "<<office<<endl;} 39 protected: 40 string office; 41 }; 42 class Faculty:public Employee 43 {public: 44 Faculty(string na,string i,string phonenum,string off,int ran):Employee(na,i,phonenum,off) 45 { rank=ran;} 46 float salresult(){ return BasicWages*rank;} 47 void print(){ cout<<"name: "<<name<<" id: "<<id<<" phonenumber: "<<phonenumber<<" office: "<<office<<" salary: "<<salresult()<<endl;} 48 private: 49 int rank; 50 }; 51 class Staff:public Employee 52 {public: 53 Staff(string na,string i,string phonenum,string off,int y,int m,int d,string pos):Employee(na,i,phonenum,off),dateHired(y,m,d) 54 { position=pos;} 55 float salresult(){ return BasicWages+Allowance*dateHired.diffYear();} 56 void print(){ cout<<"name: "<<name<<" id: "<<id<<" phonenumber: "<<phonenumber<<" office: "<<office<<" salary: "<<salresult()<<endl;} 57 private: 58 MyDate dateHired; 59 string position; 60 }; 61 int main(){ 62 Person person("Apple","1200","993"); 63 person.print(); 64 Student student("Bill","1201","994","Freshman"); 65 student.print(); 66 Employee employee("Cindy","1202","995","CandyOffice"); 67 employee.print(); 68 Faculty faculty("Daddy","1203","996","DaddyOffice",2); 69 faculty.print(); 70 MyDate in(2008,5,10); 71 Staff staff("Fred","1204","997","FredOffice",2008,5,10,"manager"); 72 staff.print(); 73 return 0; 74 }
【错误及改正方法】:一:在类内申明了一个无参数的构造函数,使用 类名::构造函数(如Person::Person)又定义一个有参数的构造函数,出现了错误;改正方法,在类内申明一个有参数的构造函数或者直接在类内编写构造函数参数初始化内容。二:从类外或者其他类试图访问类的私有成员,出现了错误;改正方法,在public成员函数中通过私有数据成员对外接口实现似有成员的访问。
【实验总结】:类的private和protected成员,在类外是不可以使用的,只有public成员可以在类外直接使用。
一:公有继承时,基类的private成员在派生类中不能访问,基类的public和protected成员在派生类中可直接访问.继承过来(变成派生类相应的public和protected成员)只有public成员在派生类外可以直接使用。
二:保护继承时,基类的private成员仍为有私有.基类的public和protected成员变成派生类的protected成员,这时在派生类外也不能直接使用原基类的public成员
三:私有继承时,基类的private成员仍为有私有。基类的public和protected成员将变成派生类的private成员。