封装可以隐藏实现细节,使代码模块化,继承可以扩展已经存在的代码模块,目的都是为了代码重用。多态是为了实现接口的重用。在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会根据句柄的类型决定调用哪个虚方法,而非对象的类型;

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

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

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

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

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

【原创】SystemVerilog中的多态和虚方法相关推荐

  1. C# 中的多态和虚方法,如何实现多态和使用虚方法?

    在 C# 中,多态(Polymorphism)是面向对象编程的基本特性之一,它允许使用不同的对象和方法来执行同一操作.C# 中实现多态的方式主要是通过虚方法和抽象类. 虚方法是一种允许子类覆盖的方法, ...

  2. java的虚方法_Java多态和虚方法调用

    多态(polymorphism) 多态的概念 ·多态是指一个程序中相同的名字表示不同的含义的情况. ·多态有两种情形: 1.编译时多态: 1.重载(overload)多个同名的不同方法: 2.如:p. ...

  3. C++中的多态——理解虚函数表及多态实现原理

    多态及其实现原理 一.多态的概念 概念 构成条件 二.虚函数的重写 重写的定义 重写的特殊情况 override和final关键字 区分重写.重载.重定义 抽象类的概念 三.多态的实现原理 父类对象模 ...

  4. C#继承与多态 virtual虚方法的使用 在子类中使用override重写父类函数

    本片文章讲的是多态 子类重写父类函数的方式如下:在父类函数使用virtual,在子类函数中使用override 注意定义变量的时候要使用new来创建,而不要使用类名 变量名的方式,否则在使用时会报错& ...

  5. C#-继承-多态-VIRTUAL虚方法(下)

    面向对象的编程中,有着一个叫做"依赖倒置原则" 程序设计要依赖与抽象类,而不依赖于具体类 比如说抽象类就相当于是父类"宠物" 具体类就是"狗狗&quo ...

  6. c++程序设计中的多态与虚函数知识点

    一.前言 如上 二.内容 编写一个程序,声明抽象基类Shape,由它派生出3个派生类:Circle(圆形).Rectangle(矩形).Triangle(三角形),用一个函数printArea输出以上 ...

  7. [转载]CLR怎样实现虚方法的多态调用(2)

    本文转载自:http://www.cnblogs.com/blusehuang/archive/2007/08/03/841707.html 在上一篇文章CLR怎样实现虚方法的多态调用(1)中主要介绍 ...

  8. C++ day22 继承(二)基类指针数组通过虚方法实现智能的多态

    继承一共有三种: 公有继承 私有继承 保护继承 文章目录 公有继承 基类和派生类的关系 is-a(用公有继承表示"是一种"的关系) has-a uses-a is-like-a i ...

  9. 三十二、C#中的虚方法、抽象类和抽象方法(里氏替换原则)

    1.虚方法 [Employee] namespace demo16 {public enum Gender{男, 女}public class Employee{public Employee() { ...

最新文章

  1. pbc是什么材料_职道漫谈 | 华为的绩效跟你们公司的绩效,有什么区别?
  2. 在Codeigniter框架中使用NuSOAP
  3. python集合的定义方式_11-Python基础知识学习—集合类型
  4. RocketMQ开发指导之三——RocketMQ编程示例
  5. Debian 9 Stretch国内常用镜像源
  6. css设置table阴影浮动效果
  7. 如何终止运行中的线程
  8. OpManager引领智能运维未来的发展方向
  9. CactiEZ-优化操作
  10. 高通 mdm9607编译以及audio框架
  11. 真正靠谱免费的数据恢复软件哪个好用?
  12. php设备巡检管理,设备巡检管理解决方案
  13. 网络安全-典型的恶意代码
  14. windows WTS 服务与桌面交互
  15. 有太多工作要做,传蚂蚁集团IPO可能推迟至2022年
  16. 语音信号短时时域分析
  17. python的tkinter插入图片_Python3 Tkinter基础 Text Photoimage 文本框中插入一张图片
  18. 今日头条“偷偷复活”内涵段子,那快播是不是也能重生了?
  19. 中药好苦,同义词词典
  20. 微信小程序精品demo:面包旅行:界面设计,文本展示,

热门文章

  1. Hacking The Box----Awkward
  2. 宝塔面板如何建立数据库
  3. 再生资源回收市场竞争分析
  4. 易语言免费版 绿色软件
  5. Vertica 向 GBase8a 迁移指南之数据类型迁移
  6. LeetCode 1375. 灯泡开关 III
  7. 这家国内最早的区块链公司6年来做了什么?
  8. 转载——考取思科CCIE证书一年后的感慨
  9. [其它]iOS 13 正式版发布 iPhone 6s或更新型号均可升级
  10. 【HoloLens2】添加空间音频学习笔记