多态(day10)
二十二 多态(Polymorphic)
函数重写(虚函数覆盖)、多态概念
如果将基类中的某个成员函数声明为虚函数,那么子类与其具有相同原型的成员函数就也将是虚函数,并且对基类中的版本形成覆盖。
这时,通过指向子类对象的基类指针,或者引用子类对象的基类引用,调用该虚函数,实际被执行的将是子类中覆盖版本,而不是基类中的原始版本,这种语法现象称为多态.
eg:
class Base{
public:
virtual void foo(void){
cout << "Base::foo" << endl;
}
};
class Derived:public Base{
public:
void foo(void){
cout << "Derived::foo" << endl;
}
};
int main(void){
Derived d;
Base* pb=&d;//pb指向子类对象的基类指针
Base& rb=d;//rb引用子类对象的基类引用
pb->foo();//Derived::foo
rb->foo();//Derived::foo
} 函数重写要求(虚函数覆盖条件)
)类中普通的成员函数可以声明为虚函数,而全局函数、类中的静态成员函数、构造函数都不能声明为虚函数。
注:析构函数可以为虚函数(后面讲)
)只有在基类中以virtual关键字修饰的函数,才能作为虚函数被子类覆盖,而与子类中virtual关键字无关。
)虚函数在子类中的覆盖版本和改函数在基类中原始版本要拥有相同的函数签名,即函数名、形参表、常属性必须严格一致.
)如果基类中的虚函数返回基本类型的数据,那么子类的覆盖版本必须返回相同的类型。
)如果基类的虚函数返回类类型指针(A*)或引用(A&),那么允许子类返回其子类的指针(B*)或引用(B&)。--类型协变
class A{};
class B:public A{}; 多态的条件
)在满足虚函数覆盖前提下,必须要通过指针或引用调用该虚函数,才能表现出来。
)调用虚函数的指针也可以是this指针,只要它是一个指针子类对象的基类指针,调用虚函数时,同样可以表现多态的特性。//重点掌握 纯虚函数、抽象类和纯抽象类
)纯虚函数
virtual 返回类型 函数名(形参表)[const]=;
)抽象类
如果一个类中包含纯虚函数,那么这个类就是抽象类,抽象类不能创建对象。
)纯抽象类(有名接口类)
如果一个抽象类除了构造函数和析构函数以外的所有成员函数都是纯虚函数,那么该类就是纯抽象类。 注:如果子类没有覆盖抽象基类的纯虚函数,那么该子类就也是一个抽象类,类的抽象属性可以被继承. eg:PDF文档阅读器 多态实现原理(了解)
通过虚函数表和动态绑定,参考poly.jpg
)动态绑定会增加内存开销
)虚函数调用会增加时间开销
)虚函数不能被内联优化
结论:如果没有多态的语法要求,最好不要使用虚函数。 虚析构函数
)基类析构函数不能调用子类的析构函数,对一个指向子类对象的基类指针使用delete运算符,实际被执行的仅是基类的析构函数,所释放的仅是基类子对象构造时的分配的动态资源,而子类特有的动态资源将会形成内存泄露。
)将基类的析构函数声明为虚函数,那么子类的析构函数就也是一个虚函数,并且可以对基类的虚析构函数形成有效的覆盖,可以表现多态的特性。
)这时delete一个指向子类对象的基类指针,实际被调用的将是子类的析构函数,而子类的析构函数在执行后又会自动调用基类的析构函数,避免内存泄露。
//笔试题:虚析构函数的作用?
=========================================
练习:薪资计算
员工
/ | \
技术员 经理 销售员
\ / \ /
技术主管 销售主管
所有员工:姓名、工号、职位等级、出勤率
经理:绩效奖金(元/月)
技术员:研发津贴(元/小时)
销售员:提成比率(x%) 薪资=基本工资+绩效工资
基本工资计算=职位等级的固定额度*出勤率(输入);
绩效工资根据具体的职位而定:
普通员工:基本工资一半
经理:绩效奖金*绩效因数(输入)
技术员:研发津贴*工作小时数*进度因数(输入)
销售员:提成比率*销售额度(输入) 技术主管:(技术员绩效工资+经理绩效工资)/
销售主管:(销售员绩效工资+经理绩效工资)/ 结果:打印员工信息,输入必要数,计算和打印工资
class 员工{
double 计算工资(){
return 基本工资() + 绩效工资();
}
virutal void 绩效工资(){}
};
class 技术员:public 员工{
void 绩效工资(){}
}
int main(){
员工对象.计算工资();
技术员对象.计算工资();
}
多态(day10)的更多相关文章
- 【JAVA零基础入门系列】Day10 Java中的数组
什么是数组?顾名思义,就是数据的组合,把一些相同类型的数放到一组里去. 那为什么要用数组呢?比如需要统计全班同学的成绩的时候,如果给班上50个同学的成绩信息都命名一个变量进行存储,显然不方便,而且在做 ...
- 【JAVA零基础入门系列】Day13 Java类的继承与多态
继承是类的一个很重要的特性,什么?你连继承都不知道?你是想气死爸爸好继承爸爸的遗产吗?(滑稽) 开个玩笑,这里的继承跟我们现实生活的中继承还是有很大区别的,一个类可以继承另一个类,继承的内容包括属性跟 ...
- 01 语言基础+高级:1-4 接口与多态_day10【接口、多态】&&day11【final、匿名内部类】
day10[接口.多态] 接口三大特征——多态引用类型转换 教学目标写出定义接口的格式写出实现接口的格式说出接口中成员的特点能够说出使用多态的前提条件理解多态的向上转型理解多态的向下转型 day10_ ...
- Java(171-194)【接口、多态】
1.接口概述与生活举例 接口就是一种公共的规范标准 只要符合规范标准,就可以大家通用 2.接口的定义基本格式 public interface 接口名称 { // 抽象方法 / ...
- Java中的多态
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal {public abstract void Say();} 子类: public class ...
- C# 工厂模式+虚方法(接口、抽象方法)实现多态
面向对象语言的三大特征之一就是多态,听起来多态比较抽象,简而言之就是同一行为针对不同对象得到不同的结果,同一对象,在不同的环境下得到不同的状态. 实例说明: 业务需求:实现一个打开文件的控制台程序的d ...
- C#非常重要基础之多态
前几天看了一位同志的博客,写的是关于他自己去支付宝面试的经历.过程大体是这样的:问答的时候,前面部分,作者都应答如流,说起自己经验如何之丰富,最后面试官问了作者一个问题:请简述多态的概念和作用.结果这 ...
- C++多态详解
多态是面向对象的程序设计的关键技术.多态:调用同一个函数名,可以根据需要但实现不同的功能.多态体现在两个方面,我们以前学过的编译时的多态性(函数重载)和现在我们这一章将要学习的运行时的多态性(虚函数) ...
- 【那些年关于java多态应用】
1.多态:具有表现多种形态的能力的特征 父类: public abstract class Animal { public abstract void Say();} 子类: public class ...
随机推荐
- wait()方法写在while循环中可以在线程接到通知后再一次判断条件
wait()方法写在while循环中可以在线程接到通知后再一次判断条件 synchronized public String pop() { String returnValue = "&q ...
- 民意调查Django实现(三)
我们接着第二小节的開始继续我们的旅程. 我们会继续Web-poll应用.而且将会专注于创建公共接口 - "Views". 哲学思想 一个视图是你的Django应用中的一个Web页面 ...
- 查看scn headroom变化趋势的几种方法
查看scn headroom变化趋势的几种方法 scn headroom问题,本文不做解释. 本文为自己的总结,脚本来自于oracle sr技术project师. 转载请注明出处http://blog ...
- 学习笔记——AOP
以下纯属个人刚了解点皮毛,一知半解情况下的心得体会: ==================================================================== AOP( ...
- Android内存解析(一)—从Linux系统内存逐步认识Android应用内存
总述 Android应用程序被限制了内存使用上限,一般为16M或24M(具体看系统设置),当应用的使用内存超过这个上限时,就会被系统认为内存泄漏,被kill掉.所以在android开发时,管理好内存的 ...
- 杂项-人物:Alan cooper
ylbtech-杂项-人物:Alan cooper Alan Cooper ,“VB之父”“交互设计之父”,荣获视窗先锋奖(Microsoft Windows Pioneer)和软件梦幻奖(Softw ...
- Django day06 模版层(二) 过滤器 标签
一: 模板语言之过滤器: " | " 前后的区分: 前面的是函数的第一个参数, 后面的是python的一个函数, 冒号后面的是第二个参数例: <p>过滤器之默认值:{ ...
- Python 45 css三种引入方式以及优先级
一:css三种引入方式 三种方式为:行间式 | 内联式 | 外联式 行间式 1.在标签头部的style属性内 2.属性值满足的是css语法 3.属性值用key:value形式赋值,value具 ...
- Android检测代理
1. System.getProperties().remove("http.proxyHost"); System.getProperties().remove("ht ...
- SQLServer2008 将本地excel导入到远程服务器表
--1.创建链接服务器,相当于创建一个访问远程数据库的快捷方式 exec sp_addlinkedserver 'TestLink', ' ', 'SQLOLEDB ', '111.11.1.111' ...