精华内容
下载资源
问答
  • 引用多态和方法多态
    千次阅读
    2019-10-12 16:21:07

    函数参数引用基类,可以在函数调用时引用派生类,实现多态。

    但是如果直接引用,基类的引用可以指向派生类,但是不能再修改引用的指向,引用是一次性的指针,直接引用不能修改指向,因此不能实现多态,通过函数参数引用的方式可以实现多态。

    更多相关内容
  • 这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:  //父类  public class ...
  • Web Services可以支持多态,不过仅仅限制在可以直接引用Web Services的时候,本文也只是起到抛砖引玉的效果,
  • 主要介绍了Java基础之方法重写和多态,结合实例形式分析了java方法重写和多态的相关原理与使用技巧,需要的朋友可以参考下
  • 本文主要给大家简单讲诉了CC++的区别以及如何使用C语言模拟实现C++继承和多态,并附上示例代码,是篇相当不错的文章,推荐给喜欢C语言的小伙伴们
  • java的编译时多态和运行时多态,保证一看就会
  • 子类从父类扩展创建之后,子类就继承了父类的属性和方法,这是SystemVerilog的继承特征,但是这个继承特征需要遵循一定的规则: v子类继承父类的所有属性(local除外)和方法; v子类可以添加新的属性和方法; v...

    封装可以隐藏实现细节,使代码模块化,继承可以扩展已经存在的代码模块,目的都是为了代码重用。多态是为了实现接口的重用。在SystemVerilog中,子类和父类之间多个子程序使用同一个名字的现象称为SystemVerilog的“多态(polymorphism)”特征。子类从父类扩展创建之后,子类就继承了父类的属性和方法,这是SystemVerilog的继承特征,但是这个继承特征需要遵循一定的规则:

    v 子类继承父类的所有属性(local除外)和方法;

    v 子类可以添加新的属性和方法;

    v 子类可以重写父类中的属性和方法;

    v 如果父类的一个方法被重写,子类必须保持和父类的原定义有一致的参数;

    v 子类可以通过super(不能使用super.super方式)操作符引用父类中的方法和成员;

    v 被声明为local的属性或方法只能对自身可见,而对于外部和子类不可见;

    v 被声明为protected的属性或方法,对外部不可见,对于自身和子类可见;

    我们知道,因为继承的特性,子类可以访问父类的属性,当子类对父类的方法进行重写,子类句柄访问的是重写后的方法。那么当父类句柄指向子类时,是否可以通过父类句柄访问子类的属性呢?默认情况下,父类句柄是不能直接访问子类的方法或者重写父类的方法。

    【示例】

    图片

    【仿真结果】

    图片

    注释掉29行后,虽然pkt指向了spkt,但是pkt还是不能访问其子类spkt中的vdisp方法,仿真会报如下错误。

    图片

    示例中,通过父类句柄直接访问子类的属性是不能访问到被子类的方法。那么通过父类句柄可以访问被子类重写的方法吗?请看下例。

    【示例】

    图片

    【仿真结果】

    图片

    可见,虽然子类对父类中的方法进行了重写,并且将父类句柄指向了子类对象,但是父类句柄和子类句柄还是访问各自类型中的方法。那么如何可以实现通过父类句柄对子类重写属性的访问呢?

    【示例】

    图片

    图片

    【仿真结果】

    图片

    示例中,pkt具有如下图的属性和方法,其中vdisp为虚方法,call_vdisp为pkt的方法,其中调用了vdisp,disp和call_disp均为非虚方法。在pkt没有指向spkt时,pkt访问disp、call_disp、vdisp、call_vdisp四种方法都是packet中的四种方法。

    图片

    spkt具有的属性如下图:

    图片

    在SystemVerilog中,子类对象的空间分配分为两个部分(如上图所示),一部分来自父类的继承部分,一部分是重写或新增的部分。spkt访问disp是,因为disp为其父类的非virtual方法,虽然sub_packet对其进行了重写,但是当spkt对其访问时,访问的是sub_packet定义的disp。vdisp访问情况同disp。当spkt访问call_disp时,因为sub_packet中没有定义call_disp,那么程序会访问内存中父类中的call_disp,call_disp是一个普通的方法,此时call_disp中调用的disp也是一个普通方法,所以此时的调用均为spkt对象中的pkt部分。当spkt仿call_vdisp时,因为call_vdisp是一个普通方法,所以此时会调用spkt中的pkt部分,但是在call_vdisp中调用的vdisp为pkt中的虚方法,并且该虚方法在spkt中进行了重定义,所以此时call_vdisp调用的vdisp为spkt中重写的vdisp。所以在spkt调用四个函数时,只有对call_disp的调用显示的是pkt中输出的信息。

    当pkt指向spkt之后,pkt调用disp、call_disp、vdisp和call_vdisp这四种方法的实际调用访问顺序如下图所示:

    图片

    当pkt调用这几种方法时,程序同样会找到spkt中的pkt部分,此时如果发现调用的方法是虚方法,那么就会在spkt中查找重写的对应的方法,如果确实存在重写的方法,那么此时就会调用spkt中的重写的方法。如果没有则会执行pkt部分的方法。

    spkt调用disp、call_disp、vdisp和call_vdisp这四种方法的实际调用访问顺序如下图所示:

    图片

    当spkt调用这几种方法时,对于spkt中的存在的方法将会直接调用,对于spkt不存在的则会访问pkt部分,在访问pkt中的方法时,如果其调用的方法为pkt中定义的虚方法,且该方法在spkt中重写,那么此时pkt中的该方法将调用spkt中重写过得方法,如示例中对call_vdisp的调用。

    通过上述几个示例,可以看到声明一种方法为虚方法的方式就是在原来方法前添加关键字virtual,子类中重写的方法可以不用添加virtual关键字,并且子类中重写的方法要和父类中该方法的参数和返回值一致。当将父类中将要被重写的方法在声明时指定为virtual方法,那么当父句柄指向子类对象的空间,此时可以实现父句柄对子类重写父类方法的访问。在SystemVerilog中子类对象的空间分配分为两个部分,一部分来自父类的继承部分,一部分是重写或新增的部分。默认情况下,父类的方法是无法访问派生类的重写和新增部分的,如果希望重写的方法被父类看到,就需要依靠本示例中的virtual方法,而虚方法正是OOP中基本的多态性结构。那么,哪些方法要定义为virtual方法呢?经常需要对从父类继承的方法进行一定的修改以适应其应用的需要的方法,在父类中对该方法定义的时候需要添加virtual关键字将该方法声明为虚方法。

    综上所述,关于虚方法我们得到以下注意事项:

    • 当使用了virtual方法,那么SystemVerilog会根据对象的类型决定调用哪个虚方法,而非句柄的类型;

    • 当没有使用virtual方法,那么SystemVerilog会根据句柄的类型决定调用哪个虚方法,而非对象的类型;

    • 如果父类的一个方法被重写,子类必须保持和父类的原定义有一致的参数;

    虚方法与重写的实现就是多态!当父类的对象指向不同的子类的时候,虚方法就表现出了不同的实现方法,呈现多态!

    下图个人技术微信公众号,欢迎朋友们关注沟通!

    图片图片图片

    本文纯属学习之用,欢迎指正文中不足,

    封面图片若有侵权,请及时沟通!

      图片图片图片

    展开全文
  • Java中的多态方法重载与方法重写。 一、多态 1.1 了解多态之前先简单了解 “绑定” 1.1.1 绑定的概念 子类重写父类方法(实现类实现接口方法)的情况下,程序调用的方法到底是调用了父类(接口)中的方法,还是...

    Java中的多态、方法重载与方法重写。

    一、多态

    1.1 了解多态之前先简单了解 “绑定”

    1.1.1 绑定的概念

    子类重写父类方法(实现类实现接口方法)的情况下,程序调用的方法到底是调用了父类(接口)中的方法,还是调用了子类(实现类)中的方法呢?我们将确定这种调用哪个方法的操作叫做绑定。

    绑定又分为静态绑定和动态绑定,又叫前期绑定和后期绑定。

    1.1.2 静态绑定(前期绑定)

    • 静态绑定就是在程序运行前就已经绑定了,即在程序编译的过程中就知道要调用的这个方法是哪个类中定义的方法了。
    • java中只有private, static, final修饰的方法以及构造方法静态绑定的.
      • private 方法的特点是只能在本类中使用,即不能被继承。
        一个方法不能被继承,那么父类对象的引用调用该方法的时候,必然是调用了父类对象中的方法。
      • static 方法又叫类方法,static修饰的成员方法能被继承,但是不能被子类覆盖,但是可以被子类 “隐藏”。static修饰的方法不依赖对象而存在,某个类的对象的引用调用了一个static方法,必定调用的是该类中的方法。
        不推荐使用对象调用静态方法。关于 “隐藏” 的概念后面会进行说明。
      • final 方法能被继承,但是不能被子类覆盖。
        某类中的方法不能被重写,该类的对象的引用调用这个方法,必定是调用了该类的对象中的方法。
      • 构造方法 不能被继承,不能被子类覆盖。
        一个类中怎么可能存在不同方法名的构造方法呢。
    • 小结: 如果一个方法不能被继承, 或者继承后不能被重写(覆盖), 那么这个方法就采用静态绑定.

    1.1.3 动态绑定(后期绑定)

    • 在程序运行时才能确定调用的是哪个类中的方法。

    1.1.4 小结

    • 关于动态绑定的原理有些复杂,我们暂时不需要知道,因为这节的标题是 “了解” 绑定嘛。
    • 我们需要知道的是: 什么是静态绑定,什么是动态绑定,绑定和Java多态有什么关系。 如下:
      • 子类重写父类方法(实现类实现接口方法)的情况下,程序调用的方法到底是调用了父类(接口)中的方法,还是调用了子类(实现类)中的方法呢?我们将确定这种调用哪个方法的操作叫绑定。
      • 静态绑定就是在程序运行前就已经绑定了,即在程序编译的过程中就知道要调用的这个方法是哪个类中定义的方法了。
      • 动态绑定就是在程序运行时才进行绑定,即在程序运行的时才能知道要调用的这个方法是哪个类中定义的方法。
      • Java的多态就是动态绑定机制。

    1.2 多态的概念

    • 同一操作作用于不同的对象,将会产生不同的结果。
    • 多态在java中最基本的体现就是:
      • 父类引用变量指向父类对象,调用方法A,调用的是父类中定义的A方法;
        父类引用变量指向子类对象,调用重载的方法A,调用的是子类中定义的A方法;
    • 按照上述两点理解,多态应该是一种运行期的状态,或者说是动态绑定。

    1.3 多态的前提

    1. 有类的继承或接口的实现;
    2. 子类要重写父类的成员方法;
    3. 父类引用指向子类对象(向上转型);

    1.4 动态多态和静态多态

    • 动态绑定被认为是动态多态, 因为只有在运行期才能知道调用的是哪个类中定义的方法;
    • 一般认为java中的方法重载是静态多态, 因为它需要在编译期决定具体调用哪个方法.
      我更倾向于方法重载和多态是没有关系的;

    1.5 注意

    • 只有非private的静态变量, 成员变量, 静态方法, 成员方法能被继承;
      代码块, 构造函数不能被继承;
      代码块应该关注的是执行顺序(静态代码块,构造代码块,构造函数,main函数之间的执行顺序);
    • 父类中非private的成员变量, 静态变量, 静态方法, final变量, final方法能被继承不能被重写, 父类中只有非private并且非final的成员方法能被重写.
      子父类中有同名静态变量同名成员变量同签名静态方法时, 父类中的这三种成分会被子类"隐藏";
      "父类的变量被子类隐藏"可以理解为使用子类引用不能调用父类的该变量;
    • 向上转型: 父类引用指向子类对象 ( Super father = new Sub(); )
      向下转型: 子类引用指向子类对象 ( Sub sub1 = (Sub) father; 或 Super father = new Sub(); )
    • “编译看左边, 运行看右边”, 右边没有, 就向上查找调用父类的;

    1.6 关于"隐藏"

    • 下面是Java文档中对隐藏域的描述:

    Within a class, a field that has the same name as a field in the superclass hides the superclass’s field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super. Generally speaking, we don’t recommend hiding fields as it makes code difficult to read.

    • 翻译成中文:
      在一个类中, 如果子父类中有同名的成员变量, 那么即使他们类型不同, 只要名字一样, 父类中的成员变量就会被隐藏; 在子类中,父类的成员变量不能被简单的用引用来访问。而是,必须从父类的引用获得父类被隐藏的成员变量,一般来说,我们不推荐隐藏成员变量,因为这样会使代码变得难以阅读。
    • 简单来说, 就是子类不能去重写覆盖父类的成员变量, 所以成员变量的访问不能像成员方法一样使用多态去访问. 这个特性同样适用于子父类中的同名静态变量和同签名静态方法;
      例如在多态环境下( Super s = new Sub(); )
    • 不推荐使用隐藏(不推荐子父类中声明同名静态变量或同名成员变量或同签名静态方法);
      不推荐使用引用调用静态方法;

    二、方法重载与方法重写

    2.1 重载和重写的概念

    • 方法重载(Overload)
      • 发生在同一个类中. 方法名必须相同, 方法的参数列表必须不同(类型, 个数, 顺序其中一个或多个条件不同), 返回值可以不同, 权限修饰符可以不同, 异常声明可以不同.
    • 方法重写/覆盖(Override)
      • 发生在子父类中. 方法名和参数列表必须相同, 返回值小于等于父类, 权限修饰符小于等于父类, 异常声明小于等于父类(小到可以不抛出异常).
        只有成员方法能被重写.
        子类不能重写父类中被final修饰的成员方法.
        子类不能重写父类中被private修饰的成员方法.

    2.2 注意

    • 重载是编译期概念, 重写(覆盖)是运行期间的概念.
    • 重载遵循所谓“编译期绑定”,即在编译时根据参数变量的类型判断应该调用哪个方法.
      重写遵循所谓“运行期绑定”,即在运行的时候,根据引用变量所指向的实际对象的类型来调用方法.
    • 我们上面说过多态是一种运行期状态,是动态绑定;
      但是重载是在编译期间就已经确定要调用哪个方法了, 所以重载不是多态, 重写才是多态;
      重载只是一种语言特性, 是一种语法规则, 与多态无关, 与面向对象也无关;
      但是很多人说重载是编译时多态, 即静态多态. 在Java中提到多态, 在不特别说明的情况下都是指动态多态;
    • 只有非private的成员方法能被重写. 成员变量不会被重写, 但是父类中的成员变量会被子类"隐藏";

    欢迎批评指正.

    展开全文
  • 静态多态和动态多态的区别其实只是在什么时候将函数实现和函数调用关联起来,是在编译时期还是运行时期,即函数地址是早绑定还是晚绑定的。静态多态是指在编译期间就可以确定函数的调用地址,并生产代码,这就是静态...
  • c++引用也有多态

    2021-02-01 21:23:36
    #include <常用> 构 矩形{ 整 x,y; 矩形(整 a,整 b):x(a),y(b){} 虚 整 取面积(){中 x*y;} }; 构 三角:公 矩形{ 用 矩形::矩形; 整 取面积(){中 x*y/2;... 打印(r....//引用,也可有多态 } ...
    #include <常用>
    构 矩形{
        整 x,y;
        矩形(整 a,整 b):x(a),y(b){}
        虚 整 取面积(){中 x*y;}
    };
    构 三角:公 矩形{
        用 矩形::矩形;
        整 取面积(){中 x*y/2;}
    };
    
    空 主(){
        三角 t{3,4};
        矩形&r=t;
        打印(r.取面积());//引用,也可有多态
    }
    
    展开全文
  • Java多态方法绑定

    2021-11-06 11:41:10
    1、多态:Java程序中一个类或多个类中定义多个同名方法,该多个同名方法完成操作不同; 2、多态表现形式 静态多态(编译时多态):通过方法重载实现 动态多态(运行时多态):通过方法重写(覆盖)实现 3...
  • 主要介绍了Python面向对象程序设计多继承和多态用法,结合实例形式分析了Python面向对象程序设计中多继承、多态的概念、原理、实现方法及相关操作注意事项,需要的朋友可以参考下
  • 引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4编程技术内幕”...
  • 多态多态的概念比较简单,就是...只有在运行过程中才能清楚调用的是具体的那个方法。重写的情况:public class Dog {public void bark(){System.out.println("woof ");}private static class Hound extends Dog...
  • 引用产生多态效果

    2021-05-14 15:27:52
    引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。 class A; class B:public A{……}; B b; A &Ref = b; // 用派生类对象初始化基类对象的引用 Ref 只能...
  • 多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法,从而实现更加灵活的编程,提高系统的可扩展性。 允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用...
  • Java多态 Python多态

    2022-03-18 23:34:59
    Java多态和Python多态 ava中的多态跟Python中的多态是有区别的。 java中的多态定义: 多态存在的三个必要条件 一、要有继承; 二、要有重写; 三、父类引用指向子类对象 java 多态演示 public class Test { public ...
  • 多态(方法多态,属性没有多态) 理论作用 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。 一个对象的实际类型是确定的,但可以指向对象的引用有很多 注意事项: 多态方法多态,属性没有多态。...
  • 静态多态和动态多态 静态多态 静态多态也称为编译时多态,即在编译时决定调用哪个方法; 静态多态一般是指方法重戟; 只要构成了方法重载,就可以认为形成了静态多态的条件; 静态多态与是否发生继承没有必然联系 ...
  • 多态是一种介于传统多态与类型擦除之间的多态实现方式,借鉴了值语义,保留了继承,在单继承的适用范围内,程序程序员都能从中受益。这篇文章主要介绍了C++值多态中的传统多态与类型擦除,需要的朋友可以参考下
  • java学习(十一)——多态方法调用

    千次阅读 2018-11-08 17:53:20
    多态 对于某一个对象(事物),在不同的时刻体现出来的不同状态叫做多态 如: 水的液态、固态和...通过继承和方法重写来实现多态。 对象间的转型问题 在java中,每个对象变量都属于一个类型,类型描述了这个...
  • 多态:即一个接口多种实现方式;C++中的多态分为两种:静态多态与动态多态 一、静态多态:也成为编译时的多态;在编译时期就已经确定要执行了的函数地址了;主要有函数重载函数模板(这里只写函数重载) (1)...
  • 1.动态绑定(auto binding):也叫后期绑定,在运行时,虚拟机根据具体对象的类型进行绑定,或者说是只有对象在虚拟机中创建了之后,才能确定方法属于哪一个对象,与引用变量实际引用的对象绑定,调用重写的方法,由...
  • java面向对象三大特性之多态---编译时多态和运行时多态详解原创颺灏发布于2019-04-01 22:17:55阅读数 494收藏一.引言1.什么是多态?说到重载和重写,大家可能都知道。它们都是多态性的体现,那么说什么是多态呢?...
  • 主要介绍了java中的多态和继承,结合实例形式分析了java中的多态和继承原理、实现方法及相关操作注意事项,需要的朋友可以参考下
  • 引用多态关系

    2020-03-18 23:34:41
    引用是除指针外另一个可以产生多态效果的手段。这意味着,一个基类的引用可以指向它的派生类实例。 【例】: class A; class B:public A{……}; B b; A &Ref = b; // 用派生类对象初始化基类对象的引用 Ref ...
  • 面向对象 1.类:众多对象抽象出来的 ...protected 受保护的 只能在该类它的子类中访问 public 公有的 在任何地方都可以访问 构造方法(函数): 作用:造对象所要调用的方法,用来创建对象,可以对
  • 众所周知,多态是面向对象语言中非常重要的一部分,多态在Java中究竟是如何实现的呢? 什么是多态 多态顾名思义,就是同一...2.子类要重写父类的方法 3.父类的引用指向子类的对象 类的继承个接口的实现 类的继承 ...
  • 》多态其实就是多种形态,多种形式:》两个最直接的体现方法重写方法重载java实现多态的方式:1、...重载是静多态,重写是动多态多态的含义:多态是指同一个方法的调用,由于对象的不同可能会有不同的行为。上述是一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 199,191
精华内容 79,676
关键字:

引用多态和方法多态