Object-Oriented Programming: Polymorphism

Slides:



Advertisements
Similar presentations
系統分析與設計 楊子青 H-1 H 、物件導向技術 n 物件導向的基本概念 – 物件、類別 – 封裝、繼承 – 同名異式 ( 多型 ) 、超荷 ( 過載 ) n 物件導向分析與設計及塑模工具 n UML 塑模工具.
Advertisements

Ch02物件導向程式設計 物件導向系統分析與設計.
Memory Pool ACM Yanqing Peng.
Java Programming Hygiene - for DIDC
資料庫設計 Database Design.
第一章 面向对象程序设计.
程設一.
類別與物件 Class & Object.
第15章 繼承與多重繼承 15-1 繼承的基礎 15-2 覆寫與隱藏父類別的成員 15-3 子類別的建構與解構子 15-4 多重繼承
Data Abstraction: The Walls
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
程設一.
刘胥影 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院.
走向C++之路 WindyWinter WindyWinter感谢诸位前来捧场。
Chapter 1 用VC++撰寫程式 Text book: Ivor Horton.
H、物件導向技術 物件導向的基本概念 物件、類別 封裝、繼承 同名異式(多型) 、超荷(過載) 物件導向分析與設計及塑模工具 UML塑模工具.
Chap 18 類別與物件 夫有土者,有大物也。有大物者,不可以物。 物而不物,故能物物。 明乎物物者之非物也,豈獨治天下百姓而已哉!
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
Scope & Lifetime 前言 Local Scope Global Functions & Objects
第六章 类的扩展与继承.
刘胥影 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院.
刘胥影 东南大学计算机学院 面向对象程序设计1 2011~2012第3学期 刘胥影 东南大学计算机学院.
Classes: A Deeper Look, Part 1
第六章 继承性和派生类 胡昊 南京大学计算机系软件所.
创建型设计模式.
刘胥影 东南大学计算机学院 面向对象程序设计1 2010~2011第3学期 刘胥影 东南大学计算机学院.
Object-Oriented Programming:
類別樣板 Class Template 類似函式樣板 由類別樣板產生的類別稱為類別樣版的實體(instance)
西安交通大学 计算机教学实验中心 大学C++程序设计教程 西安交通大学 计算机教学实验中心
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Java软件设计基础 5. 继承与多态.
第三章 C++中的C 面向对象程序设计(C++).
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
Java程序设计 第9章 继承和多态.
C#面向对象程序设计 $7 继承和多态性.
SPOTO TM JAVA课程 JAVA中的OO语法
第九單元 Classes and data abstraction I
Php class 組員: 賴羿陵 林昱廷 莊正暉 張雅晴
Java程序设计 第2章 基本数据类型及操作.
第5讲 使用类和对象编程(三) 内部类 实例 程序控制结构 选择语句.
類別與物件 I (Classes and Objects I)
第七章 操作符重载 胡昊 南京大学计算机系软件所.
第16章 虛擬與多形 16-1 虛擬函數 16-2 純虛擬函數與抽象類別 16-3 多形 16-4 虛擬繼承與虛擬解構子.
Chapter 5 Recursion.
C++程序语言设计 Chapter 3: The C in C++.
第7章 繼承/多型/介面 注意: 本投影片僅供本書上課教師使用,非經同意請勿上網轉載或供拷貝.
Classes (2) Lecture 7.
C++大学基础教程 第11章 多态性 北京科技大学 信息基础科学系 2019/4/8 北京科技大学.
潘爱民 C++ Overview 潘爱民
Speaker: Liu Yu-Jiun Date: 2009/4/29
C#程序设计基础 $3 成员、变量和常量.
中国科学技术大学计算机系 陈香兰 2013Fall 第七讲 存储器管理 中国科学技术大学计算机系 陈香兰 2013Fall.
Speaker: Liu Yu-Jiun Date: 2009/5/6
Inheritance -II.
第三章 数据抽象.
Object-Oriented Programming in C++ 第二章 类和对象
Chapter 10 Mobile IP TCP/IP Protocol Suite
C++程序设计 吉林大学计算机科学与技术(软件)学院.
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
方法進階及物件導向基礎 Lecturer: 楊昌樺.
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
第 5 章 继承、多态和虚函数 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第一讲 面向对象方法学与信息系统建模.
谭浩强编著 C++面向对象程序设计 授课教师:姬广永 学习网站:
怎樣把同一評估 給與在不同班級的學生 How to administer the Same assessment to students from Different classes and groups.
第6章 继承和多态 伍孝金
When using opening and closing presentation slides, use the masterbrand logo at the correct size and in the right position. This slide meets both needs.
Presentation transcript:

Object-Oriented Programming: Polymorphism Chapter 13 Object-Oriented Programming: Polymorphism

OBJECTIVES What polymorphism(多态) is, how it makes programming more convenient, and how it makes systems more extensible and maintainable. To declare and use virtual functions(虚函数) to effect polymorphism. The distinction between abstract and concrete classes(抽象类和具体类). To declare pure virtual functions(纯虚函数) to create abstract classes.

Topics 13.1 Introduction 13.2 Relationships Among Objects in an Inheritance Hierarchy 13.3 Type Fields and switch Statements 13.4 Abstract Classes and Pure virtual Functions 13.5 Case Study: Payroll System Using Polymorphism

13.1 Introduction ---通用化编程需求 2018年12月8日3时58分 13.1 Introduction ---通用化编程需求 画板 Tool 这里保存指针是否是保存派生类的指针?这里是否暗指需要virtual函数? 基类Shape:长方形*2、椭圆形*3、三角形*4、菱形*5等 用vector或者array来保存指针 基类指针 vs 派生类指针 当需更新画板时,枚举指针并调用各自draw函数 当需计算面积时,枚举指针并调用各自area函数

13.1 Introduction --- 需求 用户通过键盘输入多个员工信息,统计收入数据: 2018年12月8日3时58分 13.1 Introduction --- 需求 用户通过键盘输入多个员工信息,统计收入数据: (1)CommissionEmployee name, ssn, grossSales, commisionRate (2)BasePlusCommissionEmployee name, ssn, grossSales, commisionRate, baseSalary 用vector或者array来保存指向员工对象的指针 CommissionEmployee Pointer 希望通过这些通用指针来调用各自的earnings()函数以进行统计

13.1 Introduction 面向对象 数据封装 继承 多态

13.1 Introduction 多态: C++语言支持两种类型的多态: 2018年12月8日3时58分 13.1 Introduction 多态: 解释1:同样的消息被类的不同对象接收时导致的完全不同的行为的一种现象。这里所说的消息即对类的成员函数的调用。 解释2:通过指向派生类的基类指针,调用派生类的函数; 将不同的派生类对象都当作基类来处理,并根据对象不同产生不同的行为,以屏蔽各派生类对象之间的差异。写出通用的代码,使得程序员可以方便地处理普遍性问题。 C++语言支持两种类型的多态: 编译时的多态(静态多态) ——函数重载 运行时的多态(动态多态) ——虚函数 多态性提高了软件的可扩展性,使得可以用与接收消息对象类型无关的方式编写 函数重载和虚函数间的关系

Topics 13.1 Introduction 13.2 Relationships Among Objects in an Inheritance Hierarchy 13.3 Type Fields and switch Statements 13.4 Abstract Classes and Pure virtual Functions 13.5 Case Study: Payroll System Using Polymorphism

13.2 Relationships Among Objects in an Inheritance Hierarchy 13.2.1 Invoking Base-Class Functions from Derived-Class Objects(基类指针指向派生类,调用基类函数) 13.2.2 Aiming Derived-Class Pointers at Base-Class Objects(派生类指针指向基类,错误) 13.2.3 Derived-Class Member-Function Calls via Base-Class Pointers(基类指针指向派生类,调用派生类函数,错误) 13.2.4 Virtual Functions(应用虚函数,解决上述问题) 13.2.5 Summary of the Allowed Assignments Between Base-Class and Derived-Class Objects and Pointers(基类/派生类对象和指针之间的赋值)

13.2.1 Invoking Base-Class Functions from Derived-Class Objects 基类CommissionEmployee void print() const; 派生类BasePlusCommissionEmployee commissionEmployeePtr = &basePlusCommissionEmployee; 注意:基类指针调用函数,输出什么 P 13.1 - 5 程序解读

Example class B 继承 class A, 即 B is a A 正确 不调用强制类型转换 class A class B x B big; A small = big; A &refSmall = big; A *pSmall = &big; 正确 不调用强制类型转换 reinterpret_cast 不加强制类型转换会怎样? class A class B x x y y 基类部分 z 派生部分

13.2.1 Invoking Base-Class Functions from Derived-Class Objects 通过指向派生类的基类指针,调用的是基类的函数 结论: 调用基类还是派生类的函数,取决于句柄的类型,而不是句柄指向的实际对象类型

13.2.2 Aiming Derived-Class Pointers at Base-Class Objects 2018年12月8日3时58分 13.2.2 Aiming Derived-Class Pointers at Base-Class Objects 派生类指针指向基类对象 Compilation Error 第二句什么意思? P 13.6 程序解读

Example class B 继承 class A, 即 B is a A 正确 错误 考虑会产生何种后果? class A B big; A small = big; A &refSmall = big; A *pSmall = &big; 正确 big = small; B *pBig = &small; 错误 考虑会产生何种后果? reinterpret_cast 不加强制类型转换会怎样? class A class B x x y y 基类部分 z 派生部分

13.2.3 Derived-Class Member-Function Calls via Base-Class Pointers 13.2.1 通过指向派生类的基类指针,调用的是基类的函数; 可否调用派生类独有的函数? Compilation Error 结论: 通过对象句柄,仅能调用该句柄类型的成员函数 P 13.7 程序解读

13.2.3 Derived-Class Member-Function Calls via Base-Class Pointers 解决办法: downcasting If the address of a derived-class object has been assigned to a pointer of one of its direct or indirect base classes, it is acceptable to cast that base-class pointer back to a pointer of the derived-class type.

B &refBig = (B &) refSmall; Example class B 继承 class A, 即 B is a A B big; A small = big; A &refSmall = big; A *pSmall = &big; 正确 big = small; B *pBig = &small; 错误 B &refBig = (B &) refSmall; B *pBig = (B *) pSmall; × B *pBig = (B *) (&small); reinterpret_cast 为什么不能用Static_cast? class A class B x x y y 基类部分 z 派生部分

13.2.4 Virtual Functions With virtual functions, the type of the object being pointed to, not the type of the handle, determines which version of a virtual function to invoke. 虚函数: 调用哪个(基类/派生类)虚函数,由对象类型而不是句柄类型决定.

13.2.4 Virtual Functions --- 语法 基 类 class Shape{ public: virtual void draw() const; }; 派生类 class Rectangle : public Shape{ 可省略。只要基类声明函数为虚函数,则所有派生类的该函数均为虚函数

13.2.4 Virtual Functions --- 语法 基 类 class Shape{ public: virtual void draw() const; }; 派生类 class Rectangle : public Shape{ Override(覆盖) From an implementation perspective, overriding a function is no different than redefining one.

13.2.4 Virtual Functions 虚函数用于继承结构中的基类和派生类,以实现多态. 2018年12月8日3时58分 13.2.4 Virtual Functions 虚函数用于继承结构中的基类和派生类,以实现多态. 派生类中覆盖(Overridden)的虚函数和基类中的虚函数必须函数签名和返回值均相同. 包括函数名称、返回值、参数个数、类型、是否const都要一致 Rectangle rect; Shape *p = &rect; p->draw();

13.2.4 Virtual Functions 程序解读 P 13.8-10 调用虚函数的两种方式: 通过指向派生类的基类指针(或引用)调用,程序会在执行时(execution time)根据对象类型动态选择合适的派生类函数 – 动态绑定( dynamic binding )或延迟绑定( late binding ). 通过对象名和点操作符调用,程序在编译时(compile time)即根据对象类型确定函数– 静态绑定( static binding ). P 13.8-10 程序解读

13.2.4 Virtual Functions --- 若干限制 2018年12月8日3时58分 13.2.4 Virtual Functions --- 若干限制 只有类成员才能声明为虚函数 静态成员函数不能是虚函数 构造函数不能是虚函数 析构函数可以是虚函数,并且通常声明为虚函数(注意基类和派生类的析构函数不同名) 例: commissionEmployeePtr = &basePlusCommissionEmployee delete commissionEmployeePtr; 调用的是basePlusCommissionEmployee的析构函数 虚函数是为了多态设计的....静态成员函数独立于对象存在,没有this指针...所以不能设计成虚函数...

derived-class pointer 2018年12月8日3时58分 13.2.5 Summary of the Allowed Assignments Between Base-Class and Derived-Class Objects and Pointers base-class pointer derived-class pointer base-class object OK ERROR derived-class object 只有通过引用或指针来访问对象的虚函数时才进行动态绑定。 通过引用或指针访问对象的非虚成员函数,采用静态绑定。(与句柄类型的成员函数代码绑定) 通过“类名+::”访问对象成员函数,也采用静态绑定。 Employee::Print()

基类函数中调用虚函数时 Base! Derived! class Base { public: Base() {} virtual ~Base() {} virtual void print(void) { cout << "Base! "; } void get(void ) { print(); }; class derived : public Base { public: derived() {} ~derived() {} virtual void print(void) { cout << "Derived! "; } }; int main() { Base a, *ptr; derived b; a.get(); ptr = &b; ptr->get(); return 0; } Base! Derived!

{ cout<<"1"<<endl; } virtual void fuu() 2018年12月8日3时58分 class A { public: void foo() { cout<<"1"<<endl; } virtual void fuu() { cout<<"2"<<endl; } }; class B: public A { cout<<"3"<<endl; } void fuu() { cout<<"4"<<endl; } int main() { A a; B b; A *p = &a; p->foo(); p->fuu(); p = &b; B *ptr = (B *)p; ptr->foo(); ptr->fuu(); return 0; } 1 2 4 3 不一定必须是积累指针访问派生类函数,反过来可以用派生类指针指向积累对象,通过强制类型转换,不过这种转换有危险

基类构造函数中对虚函数的调用不采用动态绑定。 2018年12月8日3时58分 13.2.5 Summary of the Allowed Assignments Between Base-Class and Derived-Class Objects and Pointers 特别说明: 基类构造函数中对虚函数的调用不采用动态绑定。 通过指针访问其他成员函数并调用虚函数时仍需动态绑定。 基类构造函数中对虚函数的调用不采用动态绑定。 如何理解? 总结来说:基类部分在派生类部分之前被构造,当基类构造函数执行时派生类中的数据成员还没被初始化。如果基类构造函数中的虚函数调用被解析成调用派生类的虚函数,而派生类的虚函数中又访问到未初始化的派生类数据,将导致程序出现一些未定义行为和bug。

虚函数动态绑定的各种情况 class A {public: A() { f(); } ~A(); virtual void f(); 2018年12月8日3时58分 虚函数动态绑定的各种情况 class A {public: A() { f(); } ~A(); virtual void f(); void g(); void h() {f(); g(); } } ; class B: public A { public: B(); ~B(); void f(); }; A a; //调用A::A()和A::f a.f(); a.g(); a.h(); //调用A::h, A::f, A::g B b; //调用A::A(), A::f, B::B() b.f(); b.g(); b.h(); //调用A::h, B::f和A::g A *p; p=&a; p->f(); p->g(); p->h(); //调用A::h, A::f, A::g p=&b; p->f(); //调用B::f p->A::f(); //调用A::f p->g(); //调用A::g 静态绑定 p->h(); //调用A::h, B::f和A::g p=new B; //调用A::A(), A::f, B::B delete p; //调用A::~A() //调用B::~B, A::~A virtual ~A(); Virtual ~A()          直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。

Topics 13.1 Introduction 13.2 Relationships Among Objects in an Inheritance Hierarchy 13.3 Type Fields and switch Statements 13.4 Abstract Classes and Pure virtual Functions 13.5 Case Study: Payroll System Using Polymorphism

13.3 Type Fields and switch Statements shape类: enum ShapeType{ 长方形, 三角形, 椭圆形, 菱形}; ShapeType shapeType;// 数据成员 switch(pShape-> shapeType) case 长方形: downcast ptrShape to ptrRectangle; 画板

This is a square. This is a circle. This is a triangle. int main() { enum ShapeType{ square,circle,triangle}; class Shape{ public: Shape(ShapeType x){shapeType=x;} void MoveTo(int new_pos_x,int new_pos_y){ position_x=new_pos_x; position_y=new_pos_y; } void draw(){cout<<"This is base class: Shape!"<<endl;};// 定义绘制方法 ShapeType shapeType; private: int position_x,position_y;//定义坐标 }; class Square:public Shape{ Square(ShapeType x):Shape(x){ }; void draw(){ cout<<"This is a squre."<<endl; } int length; }; class Circle:public Shape{ Circle(ShapeType x):Shape(x){ }; cout<<"This is a circle."<<endl; } int radius; }; class Triangle:public Shape{ Triangle(ShapeType x):Shape(x){ }; cout<<"This is a triangle."<<endl; int bottom; int highness; }; 2018年12月8日3时58分 int main() { Square sq(square); Circle ci(circle); Trigon tr(triangle); Shape *pShape[]={&sq,&ci,&tr}; for(int i=0;i<3;i++){ switch(pShape[i]->shapeType) { case square: { Square *ptrSquare = (Square*) pShape[i]; ptrSquare->draw();break; } case circle: { Circle *ptrCircle=(Circle*)pShape[i]; ptrCircle->draw();break;} case triangle: { Triangle *ptrTriangle=(Triangle*)pShape[i]; ptrTriangle->draw();break;} default: break; }} return 0; } int main() { Square sq(square); Circle ci(circle); Trigon tr(triangle); Shape *pShape[]={&sq,&ci,&tr}; for(int i=0;i<3;i++){ pShape[i]->draw(); } return 0; This is a square. This is a circle. This is a triangle.

Topics 13.1 Introduction 13.2 Relationships Among Objects in an Inheritance Hierarchy 13.3 Type Fields and switch Statements 13.4 Abstract Classes and Pure virtual Functions 13.5 Case Study: Payroll System Using Polymorphism

13.4 Abstract Classes and Pure virtual Functions --- 需求 class Shape{ public: virtual void draw() const; }; 一些成员函数对于基类来说是没有意义的,将其声明为纯虚成员函数的目的是要求派生类给出其实现。

13.4 Abstract Classes and Pure virtual Functions --- 纯虚函数 Pure Virtual Function(纯虚函数): A pure virtual function is specified by placing "= 0" in its declaration, as in virtual void draw() const = 0; 对于纯虚函数,不需要在类源码中给出其实现。

13.4 Abstract Classes and Pure virtual Functions --- 抽象类和具体类 Shape obj; // Error Rectangle objRectangle; Shape *ptr = &objRectangle; // OK Shape &ref = objRectangle; // OK 作用:为派生类提供一个基本框架或公共接口。 Concrete Class(具体类): 不包含纯虚函数,可以实例化。

13.4 Abstract Classes and Pure virtual Functions --- 小结 成员函数是否声明为虚函数,取决于是否需要多态性支持 虚函数是否声明为纯虚函数,取决于该函数对于当前类是否有意义,以及当前类是否需要实例化 基类 派生类 虚函数 has an implementation gives the derived class the option of overriding the function 纯虚函数 does not provide an implementation requires the derived class to override the function ( for that derived class to be concrete; otherwise the derived class remains abstract )

Topics 13.1 Introduction 13.2 Relationships Among Objects in an Inheritance Hierarchy 13.3 Type Fields and switch Statements 13.4 Abstract Classes and Pure virtual Functions 13.5 Case Study: Payroll System Using Polymorphism

13.5 Case Study: Payroll System Using Polymorphism 目的:输出各类员工的基本信息和薪金信息 Salaried employees( 定薪员工 ) Name, SSN, Weekly Salary Hourly employees( 计时工 ) Name, SSN, Wage per hour, Hours Commission employees( 佣金制员工 ) Name, SSN, Gross sales amount, Commission rate Base-salary-plus-commission employees( 带底薪的佣金制员工 ) Name, SSN, Gross sales amount, Commission rate, Base Salary

13.5 Case Study: Payroll System Using Polymorphism

13.5.1 Creating Abstract Base Class Employee Employee Class Name, SSN: 各类员工的共有属性 print(): 输出Name, SSN等基本信息 — 虚函数 earnings(): 没有意义,要求派生类实现 — 纯虚函数 P 13.13-14 程序解读

13.5.1 Creating Abstract Base Class Employee

13.5.2 Creating Concrete Derived Class SalariedEmployee 继承Employee Class weeklySalary: 普通薪金制员工的独有属性 print(): Override基类函数, 输出基本信息和薪酬信息 earnings(): 必须Override基类的纯虚函数, 计算薪酬 P 13.15-16 程序解读

13.5.3 Creating Concrete Derived Class HourlyEmployee 继承Employee Class Wage, hours: 计时工的独有属性 print(): Override基类函数, 输出基本信息和薪酬信息 earnings(): 必须Override基类的纯虚函数, 计算薪酬 P 13.17-18 程序解读

13.5.4 Creating Concrete Derived Class CommissionEmployee 继承Employee Class grossSales, commisionRate: 佣金制员工的独有属性 print(): Override基类函数, 输出基本信息和薪酬信息 earnings(): 必须Override基类的纯虚函数, 计算薪酬 P 13.19-20 程序解读

13.5.5 Creating Indirect Concrete Derived Class BasePlusCommissionEmployee 继承CommissionEmployee Class, 间接继承Employee Class baseSalary: 带底薪的佣金制员工的独有属性 print(): Override基类(CommissionEmployee)函数, 输出基本信息和薪酬信息 earnings(): 选择Override基类的虚函数, 计算薪酬 P 13.21-22 程序解读

13.5.6 Demonstrating Polymorphic Processing 实例化四种类型员工,建立四个对象 通过对象名调用print和earnings函数(静态绑定) 通过基类指针调用print和earnings函数(动态绑定) 通过基类引用调用print和earnings函数(动态绑定) P 13.23 程序解读

Summary 多态在C++中的体现 纯虚函数 抽象类和具体类 静态多态性:通过函数重载和运算符重载实现,编译阶段 动态多态性:继承机制和虚函数,运行阶段 消息的多态;一个发送到基类对象的消息可以得到不同的解释。 纯虚函数 抽象类和具体类

Homework! 实验必选题目(交实验报告): 13.12, 13.16

13.5 Distinguish between inheriting interface and inheriting implementation. How do inheritance hierarchies designed for inheriting interface differ from those designed for inheriting implementation? ANS: When a class inherits implementation, it inherits previously defined functionality from another class. When a class inherits interface, it inherits the definition of what the interface to the new class type should be. The implementation is then provided by the programmer defining the new class type.

13.8 Distinguish between virtual functions and pure virtual functions. ANS: A virtual function must have a definition in the class in which it is declared. A pure virtual function does not provide a definition. A pure virtual function is appropriate when it does not make sense to provide an implementation for a function in a base class (i.e., some additional derived-class-specific data is required to implement the function in a meaningful manner). Classes derived directly from the abstract class must provide definitions for the inherited pure virtual functions to become a concrete class; otherwise, the derived class becomes an abstract class as well.

13.10 How does polymorphism promote extensibility? ANS: Polymorphism makes programs more extensible by making all function calls generic. When a new class type with the appropriate virtual functions is added to the hierarchy, no changes need to be made to the generic function calls. Only client code that instantiates new objects must be modified to accommodate new types.

Return class Base { public: Base() { Fuction(); } 2018年12月8日3时58分 class Base { public: Base() { Fuction(); } virtual void Fuction() { cout << "Base::Fuction" << endl; } }; class A : public Base A() { Fuction(); } { cout << "A::Fuction" << endl; } A a; Return

诊所管理系统