SystemVerilog学习——类的继承

目录

一、概述

二、基本概念

三、继承的意义

3.1 代码复用(Code Reusability)

3.2 扩展功能(Functionality Extension)

3.3 多态性(Polymorphism)

3.4 简化代码结构(Code Organization)

3.5 提升可维护性(Maintainability)

四、访问控制

五、父类方法的重载和覆盖

六、总结


一、概述

        在 SystemVerilog (SV) 中,类的继承机制与面向对象编程(OOP)中的继承概念类似,允许我们基于现有的类创建新类,以便重用代码和扩展功能。通过继承,子类可以继承父类的属性(成员变量)和方法(成员函数),并且可以覆盖父类的方法,也可以新增自己的属性和方法。继承有助于实现代码的重用、扩展和多态性。

二、基本概念

        在 SystemVerilog 中,继承通过在类定义时使用 extends 关键字来实现。子类会继承父类的所有公共和保护成员,并可以重写父类的方法,也可以添加自己的成员。

class ParentClass;// 父类成员变量int x;// 父类构造函数function new();x = 0;endfunction// 父类方法function void display();$display("x = %0d", x);endfunction
endclassclass ChildClass extends ParentClass;  // 继承父类// 子类成员变量int y;// 子类构造函数function new();super.new();  // 调用父类构造函数y = 0;endfunction// 子类重写父类的方法function void display();super.display();  // 调用父类的方法$display("y = %0d", y);endfunction
endclass
  • 继承父类的成员:子类自动继承父类的成员变量和方法,除非子类重写了这些方法或成员。
  • 重写方法:子类可以重写父类的方法,通过 functiontask 重新定义同名方法。如果子类希望在重写方法中调用父类的实现,可以使用 super 关键字来调用父类的同名方法。
  • 构造函数:子类可以定义自己的构造函数,如果子类构造函数中需要调用父类构造函数,必须使用 super.new() 显式调用父类的构造函数。
  • 成员变量的继承:子类会继承父类的成员变量,但是子类可以根据需要新增或修改成员变量。父类的成员变量在子类中保持可访问(除非是私有的)。
  • 多态性:通过继承,子类可以实现不同的行为来覆盖父类的行为,这对于在仿真中实现不同类型的对象非常有用。

        使用示例:

module test;initial begin// 创建父类和子类对象ParentClass p = new();ChildClass c = new();// 使用父类对象调用方法p.display();   // 输出 "x = 0"// 使用子类对象调用方法c.display();   // 输出 "x = 0" 和 "y = 0"end
endmodule

三、继承的意义

        继承是面向对象编程(OOP)中的一个核心概念,它在 SystemVerilog 中也有着重要的作用。继承允许我们通过从已有的类(父类)创建新的类(子类)来实现代码的复用和扩展,避免重复的代码,提高代码的可维护性和可扩展性。继承带来的好处主要有以下几个方面:

3.1 代码复用(Code Reusability)

        继承最直接的作用是实现代码的复用。子类可以继承父类的成员变量和方法,从而无需重复编写相同的代码。例如,如果你有一个基础类(父类),可以通过继承将其功能扩展到其他类(子类)中,而不需要重新实现父类已经完成的部分。

class Animal;string name;function new(string name);this.name = name;endfunctionfunction void speak();$display("Animal sound");endfunction
endclassclass Dog extends Animal;function new(string name);super.new(name);  // 调用父类构造函数endfunctionfunction void speak();$display("%s says Woof!", name);endfunction
endclass

        在这个例子中,Dog 类继承了 Animal 类的 name 成员变量和 speak() 方法,并且通过重写 speak() 方法,定义了 Dog 特有的行为。 

3.2 扩展功能(Functionality Extension)

        继承不仅仅是复用父类的代码,它还允许子类在继承的基础上扩展新的功能。子类可以通过新增自己的成员变量或方法来扩展父类的功能。这样,子类就可以在父类功能的基础上增加新的行为或特性。

class Car;string model;function new(string model);this.model = model;endfunctionfunction void drive();$display("%s is driving", model);endfunction
endclassclass ElectricCar extends Car;string battery_type;function new(string model, string battery_type);super.new(model);  // 调用父类构造函数this.battery_type = battery_type;endfunctionfunction void charge();$display("%s is charging", battery_type);endfunction
endclass

         在这个例子中,ElectricCar 类继承了 Car 类,并且新增了一个 battery_type 成员变量和一个 charge() 方法,使得电动汽车除了具备普通汽车的功能外,还可以充电。

3.3 多态性(Polymorphism)

        继承支持多态性(Polymorphism),即通过父类指针或引用来调用不同子类的实现。多态性是面向对象编程中的一种机制,它允许通过统一的接口调用不同的实现方式,极大地提高了系统的灵活性和可扩展性。

class Animal;function void speak();$display("Animal sound");endfunction
endclassclass Dog extends Animal;function void speak();$display("Woof!");endfunction
endclassclass Cat extends Animal;function void speak();$display("Meow!");endfunction
endclassmodule test;initial beginAnimal a;Dog d;Cat c;a = new();d = new();c = new();a.speak();  // 输出 "Animal sound"d.speak();  // 输出 "Woof!"c.speak();  // 输出 "Meow!"end
endmodule

         在这个例子中,Animal 是一个父类,DogCat 是它的子类。通过父类 Animal 的引用,我们可以动态地调用子类 DogCat 中的不同实现,这就是多态性。

3.4 简化代码结构(Code Organization)

        继承能够帮助我们组织代码,使得代码结构更清晰。子类通过继承父类,可以专注于实现差异化的功能,而共享和通用的功能则由父类来提供。这样可以减少重复代码,使得系统的设计更加简洁和模块化。

class Shape;function void draw();$display("Drawing shape");endfunction
endclassclass Circle extends Shape;function void draw();$display("Drawing circle");endfunction
endclassclass Square extends Shape;function void draw();$display("Drawing square");endfunction
endclass

        在这个例子中,Shape 是父类,它提供了一个通用的 draw() 方法,CircleSquare 子类重写了该方法,分别实现了不同形状的绘制功能。通过这种方式,我们可以保持代码的组织性和可扩展性。

3.5 提升可维护性(Maintainability)

        通过继承,如果父类中的逻辑发生变化,所有继承自父类的子类都可以直接受益。我们只需要修改父类中的代码,而不需要逐一修改所有子类中的代码。这极大地提高了系统的可维护性和可扩展性。

        如果父类中的 speak() 方法发生变化,所有继承自 Animal 的类都会自动更新,无需手动修改每一个子类。

四、访问控制

        在继承中,父类的成员变量和方法的访问控制(如 publicprotectedprivate)会影响子类的访问权限。

  • public:子类可以直接访问父类的公共成员。
  • protected:子类可以访问父类的受保护成员,但无法在类外部访问。
  • private:子类不能访问父类的私有成员,尽管它们可以在类内部定义和使用自己的私有成员

五、父类方法的重载和覆盖

        子类可以重载父类的方法,也可以覆盖父类的方法。如果子类方法需要调用父类的版本,可以使用 super 关键字:

class Parent;function void foo();$display("Parent foo");endfunction
endclassclass Child extends Parent;// 重写父类方法function void foo();$display("Child foo");super.foo();  // 调用父类的 foo 方法endfunction
endclass

六、总结

  • 继承使得子类可以扩展和重用父类的功能。
  • 多态性允许子类定义自己的行为,而不必修改父类代码。
  • super 关键字用于调用父类的方法和构造函数。
  • 类的成员访问控制决定了哪些成员可以被继承和访问。

        通过继承,我们可以在 SystemVerilog 中创建层次化的类结构,这对于大型验证环境和复用组件非常有帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/472351.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python学习从0到1 day29 Python 高阶技巧 ⑦ 正则表达式

目录 一、正则表达式 二、正则表达式的三个基础方法 1.match 从头匹配 2.search(匹配规则,被匹配字符串) 3.findall(匹配规则,被匹配字符串) 三、元字符匹配 单字符匹配: 注: 示例&a…

[Python学习日记-67] 封装

[Python学习日记-67] 封装 简介 如何隐藏类中的属性 封装并不是单纯意义的隐藏 封装与扩展性 特性(property) 简介 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫、小狗、小王八和小猪一起装进麻袋,然…

@Autowired 和 @Resource思考(注入redisTemplate时发现一些奇怪的现象)

1. 前置知识 Configuration public class RedisConfig {Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template new RedisTemplate<>();template.setConnectionFactory(facto…

MongoDB分布式集群搭建----副本集----PSS/PSA

MongoDB分布式集群 Replication 复制、Replica Set 复制集/副本集 概念 一、 副本集的相关概念 1.概念 “ A replica set is a group of mongod instances that maintain the same data set. ” 一组MongoDB服务器&#xff08;多个mongod实例&#xff09;&#xff08;有不…

五、函数封装及调用、参数及返回值、作用域、匿名函数、立即执行函数

1. 函数基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style&…

数据分析-48-时间序列变点检测之在线实时数据的CPD

文章目录 1 时间序列结构1.1 变化点的定义1.2 结构变化的类型1.2.1 水平变化1.2.2 方差变化1.3 变点检测1.3.1 离线数据检测方法1.3.2 实时数据检测方法2 模拟数据2.1 模拟恒定方差数据2.2 模拟变化方差数据3 实时数据CPD3.1 SDAR学习算法3.2 Changefinder模块3.3 恒定方差CPD3…

第八节 如何结合AAA实现用户远程登录-路由基础

关于调试设备的登录方式&#xff0c;一共有三种&#xff1a; 第一个&#xff1a;console&#xff1a;需要工程师在现场&#xff0c;进行登录&#xff0c;设备开局的时候使用 第二个&#xff1a;telnet ssh&#xff1a;基于网络互通的前提下进行登录的&#xff0c;远程登录 第三…

【Conda】Windows下conda的安装并在终端运行

下载 在官网下载 https://www.anaconda.com/download/success 安装 双击 一直下一步安装 配置环境变量 为了在终端运行&#xff0c;需配置环境变量 进入到安装conda的目录并复制路径 设置高级环境变量 在终端运行 输入&#xff1a; conda list表明可以正常运行 参考…

LogViewer NLog, Log4Net, Log4j 文本日志可视化

LogViewer 下载 示例&#xff1a;NLog文本日志可视化软件&#xff0c;并且能够实时监听输出最新的日志 nlog.config 通过udp方式传输给LogViewer (udp://ip:port) <?xml version"1.0" encoding"utf-8" ?> <nlog xmlns"http://www.nlog-…

MuMu模拟器安卓12安装Xposed 框架

MuMu模拟器安卓12安装Xposed 框架 当开启代理后,客户端会对代理服务器证书与自身内置证书展开检测,只要检测出两者存在不一致的情况,客户端就会拒绝连接。正是这个原因,才致使我们既没有网络,又抓不到数据包。 解决方式: 通过xposed框架和trustmealready禁掉app里面校验…

Python Web 应用开发基础知识

Python Web 应用开发基础知识 引言 随着互联网的快速发展&#xff0c;Web 应用程序的需求日益增加。Python 作为一种简单易学且功能强大的编程语言&#xff0c;已经成为 Web 开发中广受欢迎的选择之一。本文将深入探讨 Python Web 开发的基础知识&#xff0c;包括常用框架、基…

CSS Module:告别类名冲突,拥抱模块化样式(5)

CSS Module 是一种解决 CSS 类名冲突的全新思路。它通过构建工具&#xff08;如 webpack&#xff09;将 CSS 样式切分为更加精细的模块&#xff0c;并在编译时将类名转换为唯一的标识符&#xff0c;从而避免类名冲突。本文将详细介绍 CSS Module 的实现原理和使用方法。 1. 思…

动力商城-03 Idea集成apifox Mybatis-Plus字段策略

1.Idea下载apifox插件 2.新建令牌放入Idea 3.右键上传到对应接口 4.设置前置url 插件能够自动识别swagger注解 Mybatis-Plus字段策略 1、FieldStrategy作用 Mybatis-Plus字段策略FieldStrategy的作用主要是在进行新增、更新时&#xff0c;根据配置的策略判断是否对实体对…

使用 npm 安装 Yarn

PS E:\WeChat Files\wxid_fipwhzebc1yh22\FileStorage\File\2024-11\spid-admin\spid-admin> yarn install yarn : 无法将“yarn”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后…

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件 Excel导出系列目录&#xff1a;★★★★尤其注意&#xff1a;引入依赖创建导出模板类逻辑处理controllerservice 导出效果总结 Excel导出系列目录&#xff1a; 【Springboot 使用EasyExcel导出Excel文件】 【Springb…

深入理解 source 和 sh、bash 的区别

1 引言 在日常使用 Linux 的过程中&#xff0c;脚本的执行是不可避免的需求之一&#xff0c;而 source、sh、bash 等命令则是执行脚本的常用方式。尽管这些命令都能运行脚本&#xff0c;但它们之间的执行方式和效果却有着显著的区别。这些区别可能会影响到脚本的环境变量、工作…

CC6学习记录

&#x1f338; cc6 cc6和cc1的国外链其实后半条链子是一样的&#xff0c;但是cc6的不局限于jdk的版本和commons-collections的版本。 回忆一下cc1的后半条链子&#xff1a; LazyMap.get()->InvokerTransformer.transform() 这里我们就结合了URLDNS链的思路&#xff0c;在…

飞凌嵌入式RK3576核心板已适配Android 14系统

在今年3月举办的RKDC2024大会上&#xff0c;飞凌嵌入式FET3576-C核心板作为瑞芯微RK3576处理器的行业首秀方案重磅亮相&#xff0c;并于今年6月率先量产发货&#xff0c;为客户持续稳定地供应&#xff0c;得到了众多合作伙伴的认可。 FET3576-C核心板此前已提供了Linux 6.1.57…

路漫漫其修远兮,吾将上下而求索---第一次使用github的过程记录和个人感受

文章目录 1.仓库位置2.新建仓库3.配置仓库4.克隆和上传5.推荐文章和我的感受 1.仓库位置 这个仓库的位置就是在我们的这个个人主页的右上角&#xff1b;如果是第一次注册账号的话&#xff0c;这个主页里面肯定是不存在仓库的&#xff0c;需要我们自己手动的进行创建&#xff1…

docker与大模型(口语化原理和实操讲解)

文章目录 一、镜像images1&#xff09;下载安装2&#xff09;docker images相关命令(保存、删除、上传、别名、搜索镜像) 二、容器container1&#xff09;展现所有在跑的容器服务ps2&#xff09;start /restart / kill / stop /rm 三、dockerfile四、volume五、network六、dock…