面向对象编程:多态性(C++) |
您所在的位置:网站首页 › 面向对象编程多态性 › 面向对象编程:多态性(C++) |
面向对象编程:多态性(C++)文章目录面向对象编程:多态性(C++)一、简介二、类继承层次中对象之间的关系三、抽象类和纯virtual函数四、应用向下强制类型转换五、virtual析构函数六、(补充)类模板和模板类
一、简介 1、介绍:同样的消息给各种不同的对象时,会产生多种形式的结果,这就是多态性。 注: (1)、继承层次中的对象 (2)、消息是重载的函数 (因为重载的函数的签名才会一样,即函数名和类型) 2、多态性能设计和实现更具扩展性的软件系统。 3、多态性的两个底层技术:虚函数和动态绑定 (一)、静态绑定:系统在编译时就确定如何实现某一动作; (二)、动态绑定:系统在运行时动态实现某一动作(在编译时不确定执行哪段代码)。 4、多态发生的两个要素: (1)、虚函数的调用; (2)、指向派生类对象或引用的基类指针(它们不同时刻指向不同派生类的对象)。 二、类继承层次中对象之间的关系1、派生类对象可以被当做它的基类对象来处理。 不能把基类对象当做任何一个派生类的对象来处理。 GraduateStudent gs;//实例化一个派生类对象gsStudent s = gs;//基类对象指向派生类对象Student &t = gs;//基类的引用可以指向派生类Student *p = &gs;//基类的指针可以指向派生类对象gs = s;//错误,不可以派生类对象指向基类对象GraduateStudent *pGs = &s;//错误,派生类指针不可以指向基类对象2、调用的函数功能是由调用函数的句柄(指针或引用)决定的,而不是由句柄所指向的对象类型决定。 例如: /*一个基类指针指向派生类*/commissionEmployeePtr = &basePlusCommissionEmployee;//commissionEmployeePtr为基类指针,basePlusCommissionEmployee为派生类对象commissionEmployeePtr -> print();//print函数功能是由基类决定的,不是派生类。找句柄所属类的对象。3、通过基类指针调用派生类的成员函数: 1、基类指针指向派生类对象,并试图访问只在派生类中拥有的成员函数,会产生编译错误(派生类中有的成员函数基类中没有)。 2、显示把基类指针强制转化为派生类指针(向下强制类型转换),可以通过指向派生类对象的基类指针访问只在派生类中拥有的成员。 例如: /*getBaseSalary(),setBaseSalary()为派生类中的函数;commissionEmployeePtr为基类指针*/double baseSalary = commissionEmployeePtr ->getBaseSalary();commissionEmployeePtr -> setBaseSalary(500);//两条语句错误。以上情况可以用强制类型转换的方法,把基类指针commissionEmployeePtr转换成派生类指针。 4、虚函数(动态绑定) 利用虚函数,调用哪个版本的虚函数就由句柄所指向的对象类型决定,而非句柄的类型。 虚函数的定义在函数原型前加关键字virtual.函数原型和实现都加关键字。 注意:动态的绑定只发生句柄必须是基类的指针或引用,发送消息的函数是虚函数;如果是一个确定的基类对象和派生类对象,没有动态的性质。 举例: /*以下print()函数全是virtual函数*/commissionEmployeePtr = &commissionEmployee;//基类指针指向基类对象commissionEmployeePtr -> print();//此处的print()自然找基类的print()执行basePlusCommissionEmployeePtr = &basePlusCommissionEmployee;//派生类指针指向派生类对象basePlusCommissionEmployeePtr -> print();//print()找派生类中的print()操作commissionEmployeePtr = &basePlusCommissionEmployee;//基类指针指向派生类对象commissionEmployeePtr -> print();//此处print()将调用派生类中的print()函数(1)、派生类中重载的函数必须和在基类中的具有相同的原型,如以上的print函数。 (2)、用虚函数进行 动态绑定,只能通过指针或引用句柄来实现。 (3)、一旦一个函数声明为virtual,那么从整个继承层次的那一点向下的所有类中,它将保持virtual的,即使当派生类重写此函数时并没有显示的将它声明为virtual. (4)、当派生类选择不重写从其基类继承而来的virtual函数时,派生类就会简单地继承它的基类的virtual函数的实现。 三、抽象类和纯virtual函数1、抽象类:有些类通常在类的继承层次结构中作为基类,从来不实例化任何对象,这种类称为抽象类。 注: (1)、抽象类是不完整的,派生类必须定义缺少的部分。 (2)、构造一个抽象类的目的就是为其它的类提供合适的基类。 (3)、能实例化对象的类称为具体类,具体类实现了它所定义的每一个成员函数。 2、通过声明类的一个或多个virtual函数为纯虚函数,就能定义其为抽象类。 纯虚函数定义:virtual void draw() = 0;3、纯虚函数不提供函数的具体实现,每个派生的具体类必须重写所有类的纯虚函数的定义。 4、抽象类为类层次结构中的各种类定义公共的接口。抽象类包含一个或多个纯虚函数,这些函数必须在派生类中重写。 (1)、试图实例化抽象类的对象将导致编译错误。 (2)、未能在派生类中重写纯virtual函数,然后试图实例化这个派生类对象将产生编译错误。 四、应用向下强制类型转换1、向下强制类型转换 BasePlusCommissionEmployee *derivedPtr = dydynamic_cast(employee[i]);返回值:derivedPtr不为零,说明其指向一个BasePlusCommissionEmployee 对象否则,它指的不是这种BasePlusCommissionEmployee 的对象。返回运算符操作数类型的信息(要写出类型的名字) cout |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |