• 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声明虚方法就可以做到。但是如果想用父类句柄直接访问子类变量,这样是不可以的,这样只能将父类句柄转化成子类句柄,再通过子列句柄去访问。
  • 相关阅读:
    【ML-SVM案例学习】案例一:对鸢尾花数据进行SVM分类(附源码)
    springboot解决multi-statement not allow(已部署生产)
    汽车制造业安全有效的设计图纸文件外发系统是什么样的?
    pdd.order.list.get拼多多店铺订单列表查询接口(拼多多店铺订单详情接口,订单明文接口,订单解密接口,订单插旗接口,订单备注接口)代码对接教程
    声明式事务
    BDD - SpecFlow BDD 测试实践
    ubantu 安装openssh
    TP、TN、FP、FN白话解析,看这一篇就够了
    MFC Windows 程序设计[258]之枚举控件集合(附源码)
    当公路的规则与秩序,被昇腾AI时刻守护
  • 原文地址:https://blog.csdn.net/Bunny9__/article/details/126166170