-
2019-09-20 19:16:02
5.1 编译时的多态性与运行时的多态性
1、什么时多态性
【定义】
(1)在面向对象方法中,不同对象收到相同的消息时,产生不同的行为(即方法)
(2)在C++程序设计中,多态性是指用一个名字定义不同的函数,函数执行不同但类似的操作,可以实现用同一个函数名调用不同的内容的函数。“一个接口,多种方法”
2、静态联编和动态联编
【静态联编】:
定义:又称前期联编,系统在编译时就决定如何实现某一动作
特点:在程序编译时就知道调用函数的全部信息
优点:调用速度快,效率高
【动态联编】
定义:系统在运行是动态实现某一动作
特点:一直要到程序运行时才知道调用哪个函数
优点:灵活性、问题抽象性、程序易维护性
3、静态多态性与动态多样性
【静态多态性】
定义:静态联编支持的多态性称为编译时多态性,也称静态多样性
实现方式:函数重载和模板
【动态多态性】
定义:动态联编所支持的多态性称为运行时多态性,也称动态多态性
实现方式:虚函数
更多相关内容 -
PHP面向对象多态性实现方法简单示例
2020-10-19 04:14:40主要介绍了PHP面向对象多态性实现方法,简单说明了面向对象多态性的原理并结合具体实例给出了php实现多态性的相关操作技巧,需要的朋友可以参考下 -
C#中多态性的实现
2021-01-20 02:01:05动态多态性:抽象方法、重写方法、隐藏方法 二:函数重载(overlode) ——函数名必须相同 ——函数参数类型不同 ——函数参数个数不同 ——函数参数顺序不同 三:抽象(abstract) ——包含抽象函数的类,类也必须... -
运行时实现Java的多态性
2021-01-08 19:00:57Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制,下面就继承和接口实现两方面谈谈java运行时多态性的实现。 一、通过继承中超类对象引用变量引用子类对象来实现 举例... -
Java中多态性的实现方式
2020-08-29 08:31:44主要介绍了Java中多态性的实现方式,什么是多态?通过简单的一道题目帮大家理解java多态性,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
PHP5多态性与动态绑定介绍
2020-12-18 05:48:30我们创建一个接口 Shape,定义一个空的方法 draw(),那么所有的实现类都必须实现这个方法,假设 Shape 有两个实现类:Triangle 和 Rectangle,我们虽然无法通过类似这样的 Java 代码来诠释 PHP 的多态性: ... -
详解C++编程的多态性概念
2021-01-20 05:52:07多态性(polymorphism)是面向对象程序设计的一个重要特征。如果一种语言只支持类而不支持多态,是不能被称为面向对象语言的,只能说是基于对象的...在面向对象方法中一般是这样表述多态性的:向不同的对象发送同一个消息 -
C#类的多态性详解
2021-01-20 06:39:52在编译时体现的多态性是通过方法的重载来实现的。方法的重载我们听过,就是一个类对象调用若干同名,但参数类型、个数不同。类对象是根据参数类型,个数来决定调用哪个同名方法,实现何种操作。C#语言的方法重载与... -
多态性有哪些,怎么实现
2018-07-23 21:20:06C++的多态性:在基类的函数前加上virtual关键字,在派生类中重写该函数,指相同的对象收到不同的消息或者不同的对象收到相同的消息时产生的不同的实现动作。如果对象类型是派生类,就调用派生类的函数;如果对象类型...C++的多态性:在基类的函数前加上virtual关键字,在派生类中重写该函数,指相同的对象收到不同的消息或者不同的对象收到相同的消息时产生的不同的实现动作。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。支持两种多态:编译时多态(静态)、运行时多态(动态)
编译时多态:就是在编译期确定的一种多态。在C++中主要体现在函数模板,函数重载和多态无关。
运行时多态性:C++运行时多态性主要是通过虚函数来实现的。体现在具有继承关系的父类和子类之间,子类重新定义父类的成员函数成为覆盖或者重写,而虚函数允许子类重新定义父类的成员函数,即重写父类的成员函数。如p是父类指针,但是它指向的是子类对象,而且调用的又是虚函数,那么在运行期,就会找到动态绑定到父类指针上的子类对象,然后查找子类的虚函数表,找到函数f2()的入口地址,从而调用子类的f2()函数,这就是运行期多态。(动态的绑定就是指针指向的地址,用C也可以实现动态绑定,就是所谓的多态)
当涉及多态性的时候,采用了虚函数和动态绑定,此时的调用就不会在编译时候确定而是在运行时确定。不在单独考虑指针/引用的类型而是看指针/引用的对象的类型来判断函数的调用,根据对象中虚指针指向的虚表中的函数的地址来确定调用哪个函数
C++纯虚函数 :纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法,基类中实现纯虚函数的方法是在函数原型后面加“=0”。virtual void f() = 0;
1:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。
2:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态性。
3:多态用虚函数来实现,结合动态绑定.
4:抽象类是指包括至少一个纯虚函数的类
-
Java理解误区——方法的重载是多态性的一种体现?
2020-06-05 09:22:41理解误区——方法的重载是多态性的一种体现? 方法的重载是多态性的一种体现吗? 其实这是一个误区,让我很长的一段时间都理解错了,直到又一次系统复习Java的时候才理解,方法的重载并不是是多态性的一种体现. 什么...理解误区
学习的第一门语言就是Java了,还记得在初学Java的时候,还是遇到了很多的困难,很多的知识点还不能理解。提到Java的面向对象,相信很多人都会印象深刻吧,但是对于初学者来说,理解起来确实还是有些难度的。
还记得当时很不理解面向对象的多态性,就去问了问学姐,得到的答案是,暂时可以理解,方法的重载是多态性的一种体现,至于更深层次的理解,可以随着时间以后慢慢理解。
方法的重载是多态性的一种体现吗? 其实这是一个误区,让我很长的一段时间都理解错了,直到又一次系统复习Java的时候才理解,方法的重载并不是是多态性的一种体现。
下面具体谈谈方法的重载和多态性。
方法的重载
重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
特点
与返回值类型无关,只看参数列表,且参数列表必须不同。 (参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
"两同一不同":
-
同一个类、相同方法名
-
参数列表不同:参数个数不同,参数类型不同
注:判断是否为重载,跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
示例
//返回两个整数的和 int add(int x,int y){return x+y;} //返回三个整数的和 int add(int x,int y,int z){return x+y+z;} //返回两个小数的和 double add(double x,double y){return x+y;}
方法的重载、重写与多态性(方法的重载是多态性的一种体现?NO)*
从编译和运行的角度看:
重载,是指允许存在多个同名方法,而这些方法的参数不同。 编译器根据方法不同的参数表, 对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法
。 它们的调用地址在编译期就绑定了
。 Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法
。所以:对于重载而言,
在方法调用之前,编译器就已经确定了所要调用的方法
,这称为“早绑定”或“静态绑定” ;而
对于多态,只有等到方法调用的那一刻, 解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”
。
引用一句Bruce Eckel的话: “不要犯傻,如果它不是晚绑定, 它就不是多态。
”所以说,
方法的重载并不是多态性的一种体现
。下面来看看多态性
多态性
如何理解多态性?
可以理解为一个事物的多种形态。
何为多态性?
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
- 可以直接应用在抽象类和接口上
多态性的作用
提高了代码的通用性,常称作接口重用
多态性的使用
虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译,看左边;运行,看右边。
多态性的注意事项
Java引用变量有两个类型: 编译时类型和运行时类型。 编译时类型由声明该变量时使用的类型决定, 运行时类型由实际赋给该变量的对象决定。 简称: 编译时, 看左边;运行时, 看右边。
-
若编译时类型和运行时类型不一致, 就出现了对象的多态性(Polymorphism)
-
多态情况下, “看左边” : 看的是父类的引用(父类中不具备子类特有的方法);“看右边” : 看的是子类的对象(实际运行的是子类重写父类的方法)
-
对象的多态 —在Java中,子类的对象可以替代父类的对象使用
-
一个变量只能有一种确定的数据类型
-
一个引用类型变量可能指向(引用)多种不同类型的对象
Person p = new Student(); Object o = new Person();//Object类型的变量o, 指向Person类型的对象 o = new Student(); //Object类型的变量o, 指向Student类型的对象
-
-
子类可看做是特殊的父类, 所以父类类型的引用可以指向子类的对象:向上转型(upcasting)。
-
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student(); m.school = “pku”; //合法,Student类有school成员变量 Person e = new Student(); e.school = “pku”; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
-
对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)
多态性的使用前提
① 类的继承或者实现关系 ② 方法的重写 ③向上转型
多态性示例
方法声明的形参类型为父类类型,可以使用子类的对象作为实参调用该方法
public class Test { public void method(Person e) { // …… e.getInfo(); } public static void main(Stirng args[]) { Test t = new Test(); Student m = new Student(); t.method(m); // 子类的对象m传送给父类类型的参数e } }
虚拟方法调用(Virtual Method Invocation)
正常的方法调用
Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo();
虚拟方法调用(多态情况下)
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Person e = new Student(); e.getInfo(); //调用Student类的getInfo()方法
编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法。 ——动态绑定
图示
前提
Person类中定义了welcome()方法,各个子类重写了welcome()。
执行:
多态的情况下,调用对象的welcome()方法,实际执行的是子类重写的方法。
-
-
Python的多态性实例分析
2020-09-21 22:27:22主要介绍了Python的多态性,以实例形式深入浅出的分析了Python在面向对象编程中多态性的原理与实现方法,需要的朋友可以参考下 -
编程中的多态性
2014-10-17 13:55:20c++多态性,主要表现在函数调用时实现“一种接 口,多种方法”。 多态性包括编译时多态性和运行时多 态性。 -
到底什么是“多态性”?
2020-07-22 10:31:361.多态的基本概念 /** ... * @date : 2020/7/22 8:57 *面向对象有三大特征:封装、继承、多态 * 封装、继承是面向于... * 代码中的多态性,其实就是一句话,父类引用指向子类对象,就是父类可以引用不同子类的对象,产1.多态的基本概念
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 8:57 *面向对象有三大特征:封装、继承、多态 * 封装、继承是面向于类或者接口; * 多态面向的是对象,指的是对象的多态性 * -------------------------------------------------- * 代码中的多态性,其实就是一句话,父类引用指向子类对象,就是父类可以引用不同子类的对象,产生不同种 * 形态 * 格式: * 父类名称 对象名 = new 之类名称(); * 或者: * 接口名称 对象名 = new 实现类名称(); */ public class Multi { public static void main(String[] args) { // 使用多态方法 // 左侧父类的调用,指向右侧子类的对象 // 一只猫被当做动物看待是没有问题的 Animal obj = new Cat(); obj.method(); // 子类方法,new的是谁就指向谁 obj.methodFu(); // 父类特有方法,如果子类没有,就会向上找父类 } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 8:59 */ public class Animal { public void method(){ System.out.println("父类方法"); } public void methodFu(){ System.out.println("父类特有方法"); } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:00 */ public class Cat extends Animal { @Override public void method(){ System.out.println("子类方法"); } }
2.多态成员变量的使用特点
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 *访问成员变量的两种方式: * * 1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找,不会向下找。 * 2.间接通过成员方法访问成员变量: 看该方法属于谁,优先用谁,没有则向上找,不会向下找。 */ public class Multi { public static void main(String[] args) { // 使用多态的写法,父类引用指向子类对象 Fu fu = new Zi(); System.out.println(fu.num); // System.out.println(fu.age); // 错误写法,向下查找 // 子类没有覆盖重写父类方法,就是父:10 // 子类如果覆盖重写父类方法,就是子:20 fu.showNum(); } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 */ public class Fu { int num = 10; public void showNum(){ System.out.println(num); } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 */ public class Zi extends Fu { int num = 20; int age = 16; @Override public void showNum() { System.out.println(num); } }
3.多态成员方法的访问规则
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 *访问成员变量的两种方式: * * 1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找,不会向下找。 * 2.间接通过成员方法访问成员变量: 看该方法属于谁,优先用谁,没有则向上找,不会向下找。 * * 在多态的代码当中成员方法的访问规则是: * * 看new的是谁,就优先使用谁,没有则向上找。 * * 口诀:编译看左边,运行看右边。 */ public class Multi { public static void main(String[] args) { // 使用多态的写法,父类引用指向子类对象 Fu obj = new Zi(); System.out.println(obj.num); // System.out.println(fu.age); // 错误写法,向下查找 // 子类没有覆盖重写父类方法,就是父:10 // 子类如果覆盖重写父类方法,就是子:20 obj.showNum(); // 编译看左面,没问题;运行的时候method()是运行的子类中的方法 obj.method(); // 子类是new的,并且有,先用子类 // 编译看左面,没问题;运行的时候method()是运行的子类中的方法,子类中没有向上找到父类 obj.methodFu(); // 子类没有向上找 // 编译看左边,左边是Fu obj(),没有methodZi(),所以编译报如下错误 // obj.methodZi(); // 错误写法 } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 */ public class Fu { int num = 10; public void showNum(){ System.out.println(num); } public void method(){ System.out.println("父类方法"); } public void methodFu(){ System.out.println("父类特有方法"); } }
/** * @author : sunkepeng E-mail:sunkepengouc@163.com * @date : 2020/7/22 9:14 */ public class Zi extends Fu { int num = 20; int age = 16; @Override public void showNum() { System.out.println(num); } @Override public void method() { System.out.println("子类方法"); } public void methodZi(){ System.out.println("子类特有方法"); } }
4.使用口诀
成员变量:编译看左边,运行还是看左边
成员方法:编译看左边,运行看右边
5.多态的用处
就上图示例,等号左面的都是Employee对象,不关心等号右面是讲师、助教、保安等,使得代码更加灵活。
-
C# 多态性:(多态性)虚方法、抽象类、
2017-05-27 21:50:04多态性(虚方法) 1、在父类的方法中加入virtual,这个方法可以被子类重新写一遍。 在子类的方法前加入override, static void Main(string[] args) { teacher te = new teacher("teache_w"); student st =... -
多态的核心体现(方法的多态性,对象的多态性)
2019-04-20 21:03:09一、方法的多态性 (1)方法的重载 定义:同一个方法名可以根据参数列表的不同调用不同的方法体 (2)方法的覆写 定义:同一个父类的方法,可以根据实例化子类的不同也有不同的表现 二、对象的多态性 前提:... -
C++之多态性
2019-06-05 00:25:31在面向对象方法中,所谓多态性就是不同对象收到相同消息,产生不同的行为。在C++程序设计中,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数。... -
虚函数与多态性实验.docx
2020-12-12 12:58:27实用标准文案 一实验目的及要求 1进一步熟悉类的设计 运用继承与派生机制设计派生类 合理设置数据成员和成员函数 2掌握通过继承虚函数基类的指针或引用实现动态多态性的方法 3理解并掌握具有纯虚函数的抽象类的作用... -
C++实验六 多态性和虚函数的应用 课程 实验报告
2010-06-11 10:53:04C++实验六 多态性和虚函数的应用 课程 实验报告 作业参考的良品! -
C课件 第10章 多态性和虚函数.ppt
2020-10-30 09:05:39面向对象的系统常常要求一组具有相同基本语义的方法能在同一接口下为不同的对象服务这就是所谓的多态性polymorphism 所谓多态性是指发出同样的消息被不同类型的对象接收时导致完全不同的行为即指相同的函数名对应... -
[Java教程]多态性的表现形式
2021-03-17 10:52:51[Java教程]多态性的表现形式0 2015-09-05 19:00:161.什么是多态面向对象的多态性就是将父类对象应用到子类对象的特征。...2.在java语言中,多态性体现在哪些方面方法重载: 通常是指在同一个类中,相同... -
面向对象的多态性
2017-12-25 21:16:122. 面向对象的多态性 3. 抽象类与接口 A.Object类 ·Object类是所有Java类的根基类(“祖先类”) ·如果在类的声明中未使用extends关键字指明其基类,则 默认基类为Object类 a.to -
多态性实验
2013-12-03 13:17:58(2)掌握双目运算符、单目运算符的重载方法,对常用算术运算符能在自定义类中通过友元函数、成员函数进行重载,以实现静态多态性。 (3)掌握通过继承、虚函数、基类的指针或引用实现动态多态性的方法。 (4)理解... -
实现类的多态性,方法的重写和重载
2015-02-02 13:53:44在Java语言中,通过使用方法的重载和重写实现类的多态性。 2.重写(覆盖)是指父子类之间的关系,当子类继承父类中所有可能被子类访问的成员方法时,如果子类的方法名与父类的方法名相同,那么子类就不能继承父类的... -
VB 2010 (20)多态性源码.rar
2020-04-08 15:48:04通过多接口和继承实现多态性,性能更好,编程也更容易。通过反射,我们既可以使用后期绑定,也可以使用多接口,但不能使用动态创建的对象,甚至不能在运行时将DLL动态加载到应用程序中,以使用其中的类。下面分别... -
C课件第7章多态性与虚函数.docx
2020-08-20 08:49:431多态性概述 多态性的含义 在C++中多态表现为同一形式的函数调用, 可能调用不同的函数实现 多态性的表现形式 参数多态函数模板和类模板 包含多态继承了虚函数的派生类同名函数 重载多态函数重载和运算符重载 强制... -
利用虚函数实现动态多态性
2018-05-28 17:48:09虚函数的使用方法: (1)在基类中用virtual声明成员函数为虚函数。在类外定义虚函数时,不必再加virtual。 (2)在派生类中重新定义此函数时,函数名、函数类型、函数参数个数和类型必须与基类的虚函数相同,函数体... -
Java 对象 多态性的使用【非常详细】
2017-12-14 17:09:22接口不可以实例化。但是接口对象可以指向它...接口可以看做特殊的抽象类,只是所有的方法都是抽象方法(没有实现的方法),接口的方法都是默认public abstract的,所以不能被实例化。比如:List Set Map都是接口使用... -
面向对象之多态性
2020-05-08 16:52:21多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类 继承之后,可以具有不同的数据类型或表现出不同的行为 Java 实现多态有 3 个必要条件:继承、重写和向上转型。 1、继承:在多态中必须... -
C++基础:什么是C++的多态性
2020-12-28 18:50:10多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形状。 C++多态性是通过虚函数来实现的,虚函数允许子类重新定义... -
java基础~多态性
2022-01-20 21:06:45多态性下关于方法的调用 多态使用注意事项 关键字instanceof和类型转换 instanceof关键字 类型转换 关键字static 使用static修饰属性 使用static修饰方法 static关键字使用注意点 代码块 静态代码块 非...