Download presentation
Presentation is loading. Please wait.
Published byΝικόλας Σπηλιωτόπουλος Modified 6年之前
1
刘胥影 liuxy@seu.edu.cn 东南大学计算机学院
面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院
2
Polymorphism 教学要求与安排 教学要求 13.7~13.9不要求 东南大学计算机学院 11/11/2018
3
Polymorphism 13.1 多态性 13.2 多态性实例 13.3 抽象类和纯虚函数 13.4 实例研究:工资发放系统
(chap13.1, 13.2, 13.3) (chap13.3) (chap13.5) (chap13.6)
4
多态性 什么是多态性?(What) 如何产生多态性?(How) 为何需要多态性?(Why)
5
对于相同的消息net_price,类继承层次中 不同的对象根据自己的特点自动进行相应的响应
13.1多态性 什么是多态性?(1) 例1. 书 Item_base 打折书 Bulk_item 消息 响应 Item_base net_price 对象类型 Bulk_item net_price = cnt * price net_price= 𝑐𝑛𝑡∗ 1−𝑑𝑖𝑠𝑐𝑜𝑢𝑛𝑡 ∗𝑝𝑟𝑖𝑐𝑒, 𝑖𝑓 𝑐𝑛𝑡≥ min _𝑞𝑡𝑦 𝑐𝑛𝑡∗𝑝𝑟𝑖𝑐𝑒, 𝑒𝑙𝑠𝑒 对于相同的消息net_price,类继承层次中 不同的对象根据自己的特点自动进行相应的响应 东南大学计算机学院 11/11/2018
6
什么是多态性?(2) 例2. 对于相同的消息earnings,类继承层次中 不同的对象根据自己的特点自动执行相应的响应 佣金雇员
13.1多态性 什么是多态性?(2) 例2. 佣金雇员 CommissionEmployee 带底薪佣金雇员 BasePlusCommissionEmployee 消息 响应 Commission Employee BasePlusCommissionEmployee earnings 对象类型 grossSales×commissionRate baseSalary + grossSales×commissionRate 对于相同的消息earnings,类继承层次中 不同的对象根据自己的特点自动执行相应的响应 东南大学计算机学院 11/11/2018
7
什么是多态性?(3) 例3. 二维图形 TwoDimensionalShape 矩形 圆 Rectangle Circle 正方形
13.1多态性 什么是多态性?(3) 例3. 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square 东南大学计算机学院 11/11/2018
8
对于相同的消息draw/area,类继承层次中 不同的对象根据自己的特点自动执行相应的响应
13.1多态性 什么是多态性?(4) 消息 对象类型 响应 Circle Rectangle Square draw Circle Rectangle Square area 𝑎𝑟𝑒𝑎=𝑎𝑏 𝑎𝑟𝑒𝑎= 𝑎 2 𝑎𝑟𝑒𝑎=𝜋 𝑟 2 对于相同的消息draw/area,类继承层次中 不同的对象根据自己的特点自动执行相应的响应 东南大学计算机学院 11/11/2018
9
什么是多态性?(5) 多态性 同样的消息在发送给不同的对象时会产生多种形式的结果 多态性指:不同对象对同一消息的响应是多态的 13.1多态性
关键概念 消息 对象类型 响应 Circle Rectangle Square draw 同样的消息在发送给不同的对象时会产生多种形式的结果 多态性指:不同对象对同一消息的响应是多态的 东南大学计算机学院 11/11/2018
10
如何产生多态性? 多态性产生的条件 通过基类的指针或引用调用virtual函数时 知识结构 13.1多态性 二者缺一不可
多态性的产生 继承中指针和对象的关系 virtual函数与动态绑定 知识结构 条件1:基类的指针或引用 条件2:virtual函数 东南大学计算机学院 11/11/2018
11
继承中指针和对象的关系(1) 句柄 对象名 对象的指针 对象的引用 13.1多态性 A a; a.f(); //通过对象名调用
A *pr = &a; pr->f(); //通过指针调用 A &ref = a; ref.f() //通过引用调用 东南大学计算机学院 11/11/2018
12
继承中指针和对象的关系(2) 指针(引用)类型 对象类型 基类指针 基类对象 派生类指针 派生类对象 is-a 基类对象 派生类对象
13.1多态性 继承中指针和对象的关系(2) 指针(引用)类型 对象类型 基类指针 基类对象 派生类指针 派生类对象 基类对象 派生类对象 is-a 东南大学计算机学院 11/11/2018
13
继承中指针和对象的关系(3) 指针(引用)类型 对象类型 基类指针 基类对象 派生类指针 派生类对象 is-a 基类对象 派生类对象
13.1多态性 继承中指针和对象的关系(3) 指针(引用)类型 对象类型 基类指针 基类对象 派生类指针 派生类对象 基类对象 派生类对象 is-a 东南大学计算机学院 11/11/2018
14
继承中指针和对象的关系(4) is-a关系 is-a is-a 基类对象 -x -y 派生类对象 -z 基类对象 派生类对象 基类对象
13.1多态性 继承中指针和对象的关系(4) is-a关系 基类对象 -x -y 派生类对象 -z 继承的基类成员 自定义成员 基类对象 派生类对象 is-a 派生类对象用作基类对象时,只使用派生类对象中继承的基类成员x、y 基类对象 派生类对象 is-a 若将基类对象用作派生类对象,基类对象中不存在派生类中自定义的成员z 东南大学计算机学院 11/11/2018
15
继承中指针和对象的关系(5) 多态性产生的条件1:基类的指针或引用 通过基类的指针或引用调用virtual函数时会产生多态性 二维图形
13.1多态性 继承中指针和对象的关系(5) 通过基类的指针或引用调用virtual函数时会产生多态性 多态性产生的条件1:基类的指针或引用 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square 利用基类的指针向继承层级中的各个不同类的对象传递消息 is-a 东南大学计算机学院 11/11/2018
16
继承中指针和对象的关系(6) 利用基类的指针向继承层级中的各个不同类的对象传递消息 13.1多态性 消息 对象类型 Circle
Rectangle Square draw pr->draw() Circle circle; Rectangle rectangle; Square sqare; TwoDimensionalShape *pr; pr = &circle; pr->draw(); pr = &rectangle; pr = &sqare; 东南大学计算机学院 11/11/2018
17
继承中指针和对象的关系(7) 基类(派生类)指针指向基类(派生类)对象 13.1多态性 基类指针 基类对象 派生类对象 派生类指针
指针->成员函数 基类对象 派生类对象 数据段 基类的成员函数 派生类的成员函数 代码段 东南大学计算机学院 11/11/2018
18
继承中指针和对象的关系(8) 基类指针指向派生类对象 句柄:决定调用哪个类的成员函数 对象:决定操作哪个对象的数据 句柄函数 对象数据
13.1多态性 继承中指针和对象的关系(8) 基类指针指向派生类对象 基类指针 派生类对象 指针->成员函数 基类对象 派生类对象 数据段 基类的成员函数 派生类的成员函数 代码段 句柄:决定调用哪个类的成员函数 对象:决定操作哪个对象的数据 句柄函数 对象数据 东南大学计算机学院 11/11/2018
19
继承中指针和对象的关系(9) 基类指针调用派生类成员函数
13.1多态性 继承中指针和对象的关系(9) 基类指针调用派生类成员函数 基类指针只允许调用基类的成员函数,不允许调用派生 类定义的成员函数,否则会引起编译错误 若基类指针指向派生类对象,则通过向下强制类型转换 (downcasting),强制将基类指针转换为派生类指针后, 才可以访问派生类定义的成员 基类对象a -x -getX() 派生类对象b -z -getZ() A a; B b; A *p = &b; p->getX(); //ok p->getZ(); //error staic_cast<B *>(p); p->getZ(); //ok 东南大学计算机学院 11/11/2018
20
继承中指针和对象的关系(10) 多态性的要求 不能产生多态性! virtual函数 同样的消息在发送给不同的对象时会产生多种形式的结果
13.1多态性 继承中指针和对象的关系(10) 多态性的要求 同样的消息在发送给不同的对象时会产生多种形式的结果 TwoDimensionalShape::draw(){cout<<*;} 消息 对象类型 响应 Circle Rectangle Square draw 期望的响应 * pr->draw() 不能产生多态性! virtual函数 东南大学计算机学院 11/11/2018
21
virtual函数(1) virtual函数 virtual函数指示根据句柄指向的对象的类型调用与之相应的virtual函数版本 句柄函数
13.1多态性 virtual函数(1) virtual函数 关键概念 virtual函数指示根据句柄指向的对象的类型调用与之相应的virtual函数版本 句柄函数 对象数据 非virtual函数的调用 对象函数 virtual函数的调用 基类指针 派生类对象 A a; //基类 B b; //派生类 A *p = &b; //若f()为virtual函数 p->f(); //调用B::f() 东南大学计算机学院 11/11/2018
22
virtual函数(2) virtual函数定义和重写 关于派生类中重写virtual函数 重写VS.重定义
13.1多态性 virtual函数(2) virtual函数定义和重写 在基类中声明为virtual函数 在派生类中重写 关于派生类中重写virtual函数 函数原型(函数名和返回类型)不能改变 virtual关键字可以省略,但是最好保留(程序更加清晰) 不重写,则派生类直接继承它在基类中的实现 重写VS.重定义 基类函数声明为virtual 重写 基类函数未声明为virtual 重定义 virtual void draw(); 东南大学计算机学院 11/11/2018
23
virtual函数(3) virtual函数具有传递性 二维图形 TwoDimensionalShape 矩形 圆 Rectangle
13.1多态性 virtual函数(3) virtual函数具有传递性 virtual void draw(); 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square void draw(); 仍为virtual函数 是重写,不是重定义 东南大学计算机学院 11/11/2018
24
virtual函数(4) 多态性! 多态性产生的条件 通过基类的指针或引用调用virtual函数时 13.1多态性 消息 对象类型 响应
virtual void draw(); 消息 对象类型 响应 Circle Rectangle Square draw pr->draw() 多态性! 多态性产生的条件 通过基类的指针或引用调用virtual函数时 二者缺一不可 东南大学计算机学院 11/11/2018
25
virtual函数与动态绑定(1) 静态绑定(static binding): 动态绑定(dynamic/late binding):
13.1多态性 virtual函数与动态绑定(1) 静态绑定(static binding): 动态绑定(dynamic/late binding): 在编译时确定调用哪个函数 关键概念 在运行时确定调用哪个函数 静态 编译时 一般变量 一般数组 动态 运行时 动态变量 动态数组 VS. 绑定:确定调用哪个函数,即,绑定函数及其操作的对象 东南大学计算机学院 11/11/2018
26
virtual函数与动态绑定(2) virtual函数的绑定方式 通过对象名调用:静态绑定(调用该类定义的函数)
13.1多态性 virtual函数与动态绑定(2) virtual函数的绑定方式 通过对象名调用:静态绑定(调用该类定义的函数) 通过对象的指针调用:动态绑定 通过对象的引用调用:动态绑定 使用virtual函数进行动态绑定,只能通过指针或引用完成 东南大学计算机学院 11/11/2018
27
为何需要多态性?(1) 多态性使类用户能专注于普遍性问题,而从对各种不同派 生类的特性的细节的关注中解脱出来
13.1多态性 为何需要多态性?(1) 多态性使类用户能专注于普遍性问题,而从对各种不同派 生类的特性的细节的关注中解脱出来 运行环境自己根据对象类型选择相应的行为 只要类在继承层次中,类客户只需关心基类,甚至不需 知道具体类,即可执行与类对象相应的行为 消息 对象类型 响应 Circle Rectangle Square draw pr->draw() 东南大学计算机学院 11/11/2018
28
为何需要多态性?(2) 类用户可以用与接受消息的对象类型无关的方式编写, 因此提高了软件的可扩展性 二维图形
13.1多态性 为何需要多态性?(2) 类用户可以用与接受消息的对象类型无关的方式编写, 因此提高了软件的可扩展性 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square 消息 对象类型 响应 Circle Rectangle Square draw Ring 环 Ring pr->draw() 无需改变 东南大学计算机学院 11/11/2018
29
多态性实例
30
多态性实例 非virtual函数方式实现 VS. virtual函数方式实现 佣金雇员 CommissionEmployee 带底薪佣金雇员
13.2多态性实例 多态性实例 非virtual函数方式实现 VS. virtual函数方式实现 佣金雇员 CommissionEmployee 带底薪佣金雇员 BasePlusCommissionEmployee 消息 响应 Commission Employee BasePlusCommissionEmployee earnings 对象类型 grossSales×commissionRate baseSalary + grossSales×commissionRate 东南大学计算机学院 11/11/2018
31
非virtual函数方式实现(1) CommissionEmployee类 BasePlusCommissionEmployee类
13.2多态性实例 非virtual函数方式实现(1) CommissionEmployee类 类定义(Fig. 13.1) 类实现(Fig. 13.2) BasePlusCommissionEmployee类 类定义(Fig. 13.4) 类实现(Fig. 13.5) 东南大学计算机学院 11/11/2018
32
非virtual函数方式实现(2) 13.2多态性实例 Fig. 13.5: fig13_05.cpp …… 16 int main()
…… 16 int main() 17 { 18 // create base-class object 19 CommissionEmployee commissionEmployee( 20 "Sue", "Jones", " ", 10000, .06 ); 21 22 // create base-class pointer 23 CommissionEmployee *commissionEmployeePtr = 0; 24 25 // create derived-class object 26 BasePlusCommissionEmployee basePlusCommissionEmployee( 27 "Bob", "Lewis", " ", 5000, .04, 300 ); 28 29 // create derived-class pointer 30 BasePlusCommissionEmployee *basePlusCommissionEmployeePtr = 0;
33
非virtual函数方式实现(3) 13.2多态性实例 通过函数名调用, 静态绑定 Fig. 13.5: fig13_05.cpp ……
…… 35 // output objects commissionEmployee and basePlusCommissionEmployee 36 cout << "Print base-class and derived-class objects:\n\n"; 37 commissionEmployee.print(); // invokes base-class print 38 cout << "\n\n"; 39 basePlusCommissionEmployee.print(); // invokes derived-class print Print base-class and derived-class objects: commission employee: Sue Jones social security number: gross sales: commission rate: 0.06 base-salaried commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 base salary: 通过函数名调用, 静态绑定
34
基类指针指向基类对象, 静态绑定 派生类指针指向派生类对象, 静态绑定 Fig. 13.5: fig13_05.cpp
41 // aim base-class pointer at base-class object and print 42 commissionEmployeePtr = &commissionEmployee; // perfectly natural 43 cout << "\n\n\nCalling print with base-class pointer to " 44 << "\nbase-class object invokes base-class print function:\n\n"; 45 commissionEmployeePtr->print(); // invokes base-class print 46 47 // aim derived-class pointer at derived-class object and print 48 basePlusCommissionEmployeePtr = &basePlusCommissionEmployee; // natural 49 cout << "\n\n\nCalling print with derived-class pointer to " 50 << "\nderived-class object invokes derived-class " 51 << "print function:\n\n"; 52 basePlusCommissionEmployeePtr->print(); // invokes derived-class print 基类指针指向基类对象, 静态绑定 派生类指针指向派生类对象, 静态绑定 commission employee: Sue Jones social security number: gross sales: commission rate: 0.06 base-salaried commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 base salary:
35
非virtual函数方式实现(5) 13.2多态性实例 基类指针指向派生类对象, 静态绑定 函数:基类的print()
Fig. 13.5: fig13_05.cpp 54 // aim base-class pointer at derived-class object and print 55 commissionEmployeePtr = &basePlusCommissionEmployee; 56 cout << "\n\n\nCalling print with base-class pointer to " 57 << "derived-class object\ninvokes base-class print " 58 << "function on that derived-class object:\n\n"; 59 commissionEmployeePtr->print(); // invokes base-class print 60 cout << endl; 基类指针指向派生类对象, 静态绑定 函数:基类的print() 数据: basePlusCommissionEmployee的数据 若此处: commissionEmployeePtr->earnings (); 结果? commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 5000 * 0.04 = 200 注意:没有baseSalary
36
非virtual函数方式实现(6) 13.2多态性实例 错误 不可将派生类指针指向基类对象, 基类对象不是一个(is-a)派生类对象
Fig. 13.6: fig13_06.cpp 6 int main() 7 { 8 CommissionEmployee commissionEmployee( 9 "Sue", "Jones", " ", 10000, .06 ); 10 BasePlusCommissionEmployee *basePlusCommissionEmployeePtr = 0; 11 12 // aim derived-class pointer at base-class object 13 // Error: a CommissionEmployee is not a BasePlusCommissionEmployee 14 basePlusCommissionEmployeePtr = &commissionEmployee; 15 return 0; 16 } // end main 错误 不可将派生类指针指向基类对象, 基类对象不是一个(is-a)派生类对象
37
非virtual函数方式实现(7) 13.2多态性实例 OK, 基类的函数 错误, 派生类的函数
Fig. 13.6: fig13_06.cpp 7 int main() 8 { 9 CommissionEmployee *commissionEmployeePtr = 0; // base class 10 BasePlusCommissionEmployee basePlusCommissionEmployee( 11 "Bob", "Lewis", " ", 5000, .04, 300 ); // derived class 12 14 commissionEmployeePtr = &basePlusCommissionEmployee; 15 18 string firstName = commissionEmployeePtr->getFirstName(); 19 string lastName = commissionEmployeePtr->getLastName(); 20 string ssn = commissionEmployeePtr->getSocialSecurityNumber(); 21 double grossSales = commissionEmployeePtr->getGrossSales(); 22 double commissionRate = commissionEmployeePtr->getCommissionRate(); 23 26 double baseSalary = commissionEmployeePtr->getBaseSalary(); 27 commissionEmployeePtr->setBaseSalary( 500 ); 28 return 0; 29 } // end main OK, 基类的函数 错误, 派生类的函数
38
virtual函数方式实现(1) 13.2多态性实例 virtual函数, 动态绑定 9 class CommissionEmployee
10 { 11 public: 12 CommissionEmployee( const string &, const string &, const string &, 13 double = 0.0, double = 0.0 ); 14 15 void setFirstName( const string & ); // set first name 16 string getFirstName() const; // return first name 17 ……. 30 virtual double earnings() const; // calculate earnings 31 virtual void print() const; // print CommissionEmployee object 32 private: 33 string firstName; 34 string lastName; 35 string socialSecurityNumber; 36 double grossSales; // gross weekly sales 37 double commissionRate; // commission percentage 38 }; // end class CommissionEmployee Fig. 13.8: CommissionEmployee.h virtual函数, 动态绑定 东南大学计算机学院 11/11/2018
39
virtual函数方式实现(2) 13.2多态性实例 virtual函数, 基类函数的重写
13.9: BasePlusCommissionEmployee.h 10 #include "CommissionEmployee.h" // CommissionEmployee class declaration 11 12 class BasePlusCommissionEmployee : public CommissionEmployee 13 { 14 public: 15 BasePlusCommissionEmployee( const string &, const string &, 16 const string &, double = 0.0, double = 0.0, double = 0.0 ); 17 18 void setBaseSalary( double ); // set base salary 19 double getBaseSalary() const; // return base salary 20 21 virtual double earnings() const; // calculate earnings 22 virtual void print() const; // print BasePlusCommissionEmployee object 23 private: 24 double baseSalary; // base salary 25 }; // end class BasePlusCommissionEmployee virtual函数, 基类函数的重写 东南大学计算机学院 11/11/2018
40
virtual函数方式实现(3) 13.2多态性实例 基类指针指向基类对象, 动态绑定 函数: 基类的print()
Fig : fig13_10.cpp 45 // aim base-class pointer at base-class object and print 46 commissionEmployeePtr = &commissionEmployee; 47 cout << "\n\nCalling virtual function print with base-class pointer" 48 << "\nto base-class object invokes base-class " 49 << "print function:\n\n"; 50 commissionEmployeePtr->print(); // invokes base-class print 基类指针指向基类对象, 动态绑定 函数: 基类的print() 数据: commissionEmployee的数据 若此处: commissionEmployeePtr->earnings (); 结果? commission employee: Sue Jones social security number: gross sales: commission rate: 0.06 10000 * 0.06 = 600
41
virtual函数方式实现(4) 13.2多态性实例 基类指针指向派生类对象, 动态绑定 函数: 派生类的print()
Fig : fig13_10.cpp 59 // aim base-class pointer at derived-class object and print 60 commissionEmployeePtr = &basePlusCommissionEmployee; 61 cout << "\n\nCalling virtual function print with base-class pointer" 62 << "\nto derived-class object invokes derived-class " 63 << "print function:\n\n"; 64 67 commissionEmployeePtr->print(); 基类指针指向派生类对象, 动态绑定 函数: 派生类的print() 数据: basePlusCommissionEmployee的数据 若此处: commissionEmployeePtr->earnings (); 结果? base-salaried commission employee: Bob Lewis social security number: gross sales: commission rate: 0.04 base salary: * 0.04 = 500 注意:有baseSalary
42
抽象类和纯virtual函数 抽象类和具体类 抽象类和纯virtual函数
43
抽象类和具体类(1) 根据是否实例化对象 具体类(concrete class):可以实例化对象
13.3抽象类和具体类 抽象类和具体类(1) 根据是否实例化对象 具体类(concrete class):可以实例化对象 抽象类(abstract class):不能实例化对象 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square 环 Ring 抽象类 (抽象基类) 具体类 具体类 具体类 具体类 东南大学计算机学院 11/11/2018
44
ThreeDimensionalShape
13.3抽象类和具体类 抽象类和具体类(2) 二维图形 TwoDimensionalShape 圆 Circle 矩形 Rectangle 正方形 Square 环 Ring 图形 Shape 三维图形 ThreeDimensionalShape 球 Sphere 立方体Cube 抽象类 (抽象基类) 抽象类 抽象类 具体类 具体类 具体类 具体类 具体类 具体类 抽象类为其派生类定义了公共的通用接口 东南大学计算机学院 11/11/2018
45
virtual void draw() const = 0;
13.3抽象类和具体类 抽象类和纯virtual函数(1) 如何定义抽象类 纯virtual函数 不提供virtual函数的具体实现 纯virtual函数是不完整的 派生的具体类必须重写所有基类的纯virtual函数的定义 至少声明一个virtual函数为纯virtual函数(pure virtual function) virtual void draw() const = 0; pure specifier 可包含数据成员和具体的成员函数 东南大学计算机学院 11/11/2018
46
抽象类和纯virtual函数(2) virutal函数 VS. 纯virtual函数 virtual函数 纯virtual函数 函数实现 有
13.3抽象类和具体类 抽象类和纯virtual函数(2) virutal函数 VS. 纯virtual函数 virtual函数 纯virtual函数 函数实现 有 没有 类的种类 具体类 抽象类 类定义 完整 不完整 派生类中重写 重写 不重写直接继承 重写具体类 不重写抽象类 东南大学计算机学院 11/11/2018
47
实例研究:工资发放系统 继承层次 实现
48
BasePlusCommissionEmployee
13.4实例研究 继承层次(1) 分析:数据成员 雇员 Employee 薪金雇员 SalariedEmployee 佣金雇员 CommissionEmployee 钟点雇员 HourlyEmployee 带底薪佣金雇员 BasePlusCommissionEmployee first name, last name, social security number first name, last name, social security number, salary first name, last name, social security number, hours, wage first name, last name, social security number, commission rate, gross sales first name, last name, social security number, commission rate, gross sales, base salary 东南大学计算机学院 11/11/2018
49
13.4实例研究 继承层次(2) 分析: 成员函数 东南大学计算机学院 11/11/2018
50
BasePlusCommissionEmployee
13.4实例研究 继承层次(3) 第1步:确定根类 第2步:确定派生类中需要增加的成员 CommissionEmployee -commissionRate -grossSales SalariedEmployee -salary HourlyEmployee -hours -wage BasePlusCommissionEmployee -baseSalary Employee -fistName -lastName -socialSecurityNumber -earnings() -print()
51
BasePlusCommissionEmployee
13.4实例研究 继承层次(4) 第3步:确定派生类间的继承关系 Employee -fistName -lastName -socialSecurityNumber -earnings() -print() CommissionEmployee -commissionRate -grossSales SalariedEmployee -salary HourlyEmployee -hours -wage BasePlusCommissionEmployee -baseSalary
52
BasePlusCommissionEmployee
13.4实例研究 继承层次(5) 雇员 Employee 薪金雇员 SalariedEmployee 佣金雇员 CommissionEmployee 钟点雇员 HourlyEmployee 带底薪佣金雇员 BasePlusCommissionEmployee 东南大学计算机学院 11/11/2018
53
继承层次(6) 第4步: 确定纯virtual函数 和virtual函数, 并确定: 抽象类和具体类 -earnings()为
13.4实例研究 继承层次(6) 第4步: 确定纯virtual函数 和virtual函数, 并确定: 抽象类和具体类 -earnings()为 纯virtual函数 -print()为 virtual函数 Employee为抽象类 其他类为具体类 东南大学计算机学院 11/11/2018
54
Fig : Employee.h 9 class Employee 10 { 11 public: 12 Employee( const string &, const string &, const string & ); 13 14 void setFirstName( const string & ); // set first name 15 string getFirstName() const; // return first name 16 17 void setLastName( const string & ); // set last name 18 string getLastName() const; // return last name 19 20 void setSocialSecurityNumber( const string & ); // set SSN 21 string getSocialSecurityNumber() const; // return SSN 22 23 // pure virtual function makes Employee abstract base class 24 virtual double earnings() const = 0; // pure virtual 25 virtual void print() const; // virtual 26 private: 27 string firstName; 28 string lastName; 29 string socialSecurityNumber; 30 }; // end class Employee 根类定义,抽象基类 cpp文件中不包含earnings()函数的实现
55
Fig. 13.15: SalariedEmployee.h
8 class SalariedEmployee : public Employee 9 { 10 public: 11 SalariedEmployee( const string &, const string &, 12 const string &, double = 0.0 ); 13 14 void setWeeklySalary( double ); // set weekly salary 15 double getWeeklySalary() const; // return weekly salary 16 17 // keyword virtual signals intent to override 18 virtual double earnings() const; // calculate earnings 19 virtual void print() const; // print SalariedEmployee object 20 private: 21 double weeklySalary; // salary per week 22 }; // end class SalariedEmployee 派生类定义,具体类 30 double SalariedEmployee::earnings() const 31 { 32 return getWeeklySalary(); 33 } // end function earnings Fig : SalariedEmployee.cpp 必须重写earnings()函数
56
Fig : HourlyEmployee.h 8 class HourlyEmployee : public Employee 9 { 10 public: 11 HourlyEmployee( const string &, const string &, 12 const string &, double = 0.0, double = 0.0 ); 13 14 void setWage( double ); // set hourly wage 15 double getWage() const; // return hourly wage 16 17 void setHours( double ); // set hours worked 18 double getHours() const; // return hours worked 19 20 // keyword virtual signals intent to override 21 virtual double earnings() const; // calculate earnings 22 virtual void print() const; // print HourlyEmployee object 23 private: 24 double wage; // wage per hour 25 double hours; // hours worked for week 26 }; // end class HourlyEmployee 派生类定义,具体类
57
Fig. 13.18: HourlyEmployee.cpp
44 double HourlyEmployee::earnings() const 45 { 46 if ( getHours() <= 40 ) // no overtime 47 return getWage() * getHours(); 48 else 49 return 40 * getWage() + ( ( getHours() - 40 ) * getWage() * 1.5 ); 50 } // end function earnings 必须重写earnings()函数
58
8 class CommissionEmployee : public Employee
9 { 10 public: 11 CommissionEmployee( const string &, const string &, 12 const string &, double = 0.0, double = 0.0 ); 13 14 void setCommissionRate( double ); // set commission rate 15 double getCommissionRate() const; // return commission rate 16 17 void setGrossSales( double ); // set gross sales amount 18 double getGrossSales() const; // return gross sales amount 19 20 // keyword virtual signals intent to override 21 virtual double earnings() const; // calculate earnings 22 virtual void print() const; // print CommissionEmployee object 23 private: 24 double grossSales; // gross weekly sales 25 double commissionRate; // commission percentage 26 }; // end class CommissionEmployee Fig : CommissionEmployee.h 派生类定义,具体类 43 double CommissionEmployee::earnings() const 44 { 45 return getCommissionRate() * getGrossSales(); 46 } // end function earnings 必须重写earnings()函数 Fig : CommissionEmployee.cpp
59
Fig. 13.21: BasePlusCommissionEmployee.h
8 class BasePlusCommissionEmployee : public CommissionEmployee 9 { 10 public: 11 BasePlusCommissionEmployee( const string &, const string &, 12 const string &, double = 0.0, double = 0.0, double = 0.0 ); 13 14 void setBaseSalary( double ); // set base salary 15 double getBaseSalary() const; // return base salary 16 17 // keyword virtual signals intent to override 18 virtual double earnings() const; // calculate earnings 19 virtual void print() const; // print BasePlusCommissionEmployee object 20 private: 21 double baseSalary; // base salary per week 22 }; // end class BasePlusCommissionEmployee 间接派生类定义,具体类 32 double BasePlusCommissionEmployee::earnings() const 33 { 34 return getBaseSalary() + CommissionEmployee::earnings(); 35 } // end function earnings Fig : BasePlusCommissionEmployee.cpp
60
Polymorphism 教学要求与安排 教学要求 13.7~13.9不要求 东南大学计算机学院 11/11/2018
61
作业 deadline: 5.19 24:00 H7: Ex. 13.12, 13.16 deadline: 5.24 24:00
东南大学计算机学院 11/11/2018
Similar presentations