Presentation is loading. Please wait.

Presentation is loading. Please wait.

刘胥影 liuxy@seu.edu.cn 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 liuxy@seu.edu.cn 东南大学计算机学院.

Similar presentations


Presentation on theme: "刘胥影 liuxy@seu.edu.cn 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 liuxy@seu.edu.cn 东南大学计算机学院."— Presentation transcript:

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


Download ppt "刘胥影 liuxy@seu.edu.cn 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 liuxy@seu.edu.cn 东南大学计算机学院."

Similar presentations


Ads by Google