• SV 类的虚方法 多态


    SV 类的虚方法 多态 类型转换

    概述

    • 类的成员方法可以加修饰词virtual(虚方法)
    • 虚方法是一种基本的多态结构
    • 一个虚方法可以覆盖基类的同名方法
    • 在父类和子类中声明虚方法,其方法名、参数名、参数方向都应该保持一致
    • 在调用虚方法时,它将调用句柄指向对象的方法,而不受句柄类型的影响
    class BasePacket;
      int A = 1;
      int B = 2;
      
      function void printA;
        $display("BasePacket::A is %d", A);
      endfunction
      
      virtual function void printB;
        $display("BasePacket::B is %d", B);
      endfunction
    
    endclass
    
    class My_Packet extends BasePacket;
      int A = 3;
      int B = 4;
    
      function void printA;
        $display("My_Packet::A is %d", A);
      endfunction
    
      virtual function void printB;
        $display("My_Packet::B is %d", B);  
      endfunction
    
    endclass
    
    module tb;
      BasePacket P1 = new();
      My_Packet P2 = new();
    
      initial begin
        P1.printA;  // A is 1
        P1.printB;  // B is 2
        P1 = P2;    // 子类句柄赋值给父类,父类句柄指向子类的对象
        P1.printA;  // A is 1
        P1.printB;  // B is 4
        P2.printA;  // A is 3
        P2.printB;  // B is 4
      end
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    在这里插入图片描述
    在这里插入图片描述

    父类句柄默认会查找调用父类方法,当子类句柄赋值给父类,父类句柄指向子类的对象后,父类句柄查找方法会扩大到子类里,如果子类里有同名方法,那么就会执行子类的同名方法。故P1.printB()P2.printB()打印结果都是4。
    virtual关键字的作用:虽然句柄类型不一样,但是调用函数会以子类的实现优先,即子类如果有同名方法就调用子类里的方法。


    变量能不能也声明成virtual:不可以

    • 人家都叫虚方法了,都没说虚变量诶
    • 父类访问方法的范围可以扩展到子类,但是访问的变量范围只有父类变量范围
    • 上述代码子类方法可以不用virtual声明,但是父类一定要声明
    • 上述代码,父类不用virtual,子类用virtual,则不行,这样父类对象在查找方法时候,不知道要去子类找,只会在父类范围内查找

    一些建议点:

    • 类在封装的时候建议不要local、protected
    • 类在继承的时候,为了方便以后访问到更多的变量,子类继承父类的时候尽量不要出现同名变量

    2022/08/06
    再补充一下

    • 子类句柄可以直接赋值给父类句柄,这样相当于从大三角形到小三角形,在缩小范围;
    • 直接将父类句柄赋值给子类句柄的时候会报错,需要使用$cast()系统函数做类型转换;
    • 父类的句柄如果想要访问子类的方法,使用vritual声明虚方法就可以做到。但是如果想用父类句柄直接访问子类变量,这样是不可以的,这样只能将父类句柄转化成子类句柄,再通过子列句柄去访问。
  • 相关阅读:
    mysql事务隔离级别案例(一)
    django的使用步骤详细
    pytest 运行方式、常用参数、前后置条件
    计算机毕业设计Java东软在线学习平台(源码+系统+mysql数据库+lw文档)
    JUC中的AQS底层详细超详解
    IB课程 EE怎么写?
    前端必备:Node.js是什么?它有哪些特点和优势?
    黑*头条_第1章_项目介绍和工程搭建
    江川第一镰启动仪式 国稻种芯:北大荒2300余万亩水稻收获
    ftp靶机_获取shell
  • 原文地址:https://blog.csdn.net/Bunny9__/article/details/126166170