【sv中的继承与多态】

继承

在验证的过程中,经常会有新的测试用例被添加进来,而且需要对原有的验证平台进行改进,特殊的测试用例经常会要求验证平台添加特定的功能。在过程化编程语言中,这要求修改原来的代码并且有可能修改原有的数据结构,这个过程可能会在原有的验证环境中引入意外的错误。面向对象编程语言提供了一个高层次的重用功能:通过对已有的基类引申或者扩展,生成新的子类。
所谓继承,就是指从父类扩展创建出的新的派生类(子类)继承了父类中的成员,属性和方法。

在继承的过程中,存在如下的一些基本规则。
1)子类继承父类的所有数据成员和方法。
2)子类可以添加新的数据成员或者方法。
3)子类可以重写基类中的数据成员和方法,也就是重写。
4)如果一个方法被子类重写,其必须保持和基类的原定义有一致的参数。
5)子类可以通过super操作符引用父类中的方法和成员。
6)被声明为 local的数据成员或方法只能对自身可见,而对于外部和子类不可见;

class packet;
	integer status;
	task rst();
	status = 0;
	endtask
	endclass
class Deriverpacket extends packet;
	integer a, b, c;
task showstattus();
$display(status);
endtask
endclass

如上:子类Deriverpacket继承了packet中所以的数据成员和方法,并可以添加新的数据成员或者方法。

类的重写实例:

class packet;
	int status = 4;
	function int chkstat(int s);
		return(status == s);
	endfunction
	endclass
class Derivedpacket extends packet;
	int status = 15;
	function void chkstat(int s);
		$display(status);
	endfunction
endclass

在扩展的过程中,子类 Derivedpacket重写了父类中原有的成员和方法。其中,将 status的初值设置为 15,而 chkstat改为打印信息而不是返回数值。

多态

对于子类对象来说,当子类对象调用一个重写于父类的方法时,即子类中与父类同名的的方法,此时父类中的方法会被调用,而不是重写的那一个。因为默认情况下,子类中重写的方法对父类是不可见的。
在这里插入图片描述

虚方法

假如我们希望重写的方法能够被父类看得到,该如何处理呢?也就是说,假如我们希望build_packet能够调用子类中重写的build_payld,我们可以在类中的方法被定义的时候通过添加virtual关键字来声明一个虚方法,虚方法是一个基本的多态性结构。虚方法为具体的实现提供了一个原型,也就是说派生类中,重写该方法的时候必须采用一致的参数和返回值。

class basepacket;
	int A=1;
	int A=2;
	function void printA;
		$display("Basepacket::A is % d", A);
	endfunction:printA
	virtual function void printB;
		$display("Basepacket::B is % d", B);
	endfunction:printB
endclass:Basepacket
class My_packet extends Basepacket;
	int A = 3 ;
	int B =4;
	function void printA;
		$display("My_packet::A is % d", A);
		endfunction : printA
	virtual function void printB;
		$display("My_packet::B is % d", B);
	endfunction:printB
	endclass :My_packet
	...
	Basepacket p1 = new;
	My_packet p2 = new;
	intial begin
	p1.printA; 			//打印Basepacket::A is 1
	p1.printB;			//打印Basepacket::B is 2
	p1=p2; 				//p1指向My_packet 对象
	p1.printA;			//打印Basepacket::A is 1
	p1.printB;			//打印My_packet::B is 4
	p2.printA;			//打印My_packet::A is 3
	p2.printB;			//打印My_packet::B is 4
	end

在 p1指向 p2后,当 p1.printA 被调用的时候,程序会调用访问内存中类对象 p2中 p1 的部分,而此时发现printA是一个普通方法,为此直接调用并结束访问

p1.printB被调用的时候,程序同样找到类对象p2中p1的部分,此时发现 printB是个虚方法,这时其会咨询系统,查看整个 p2在定义的时候是否重写了该方法,系统发现在p2中(除了p1外)确实重写了该方法,为此,程序会直接调用 p2重写的实现;为此输出会是 My_packet::B is 4。

封装可以隐藏实现细节,使得代码模块化,继承可以扩展已存在的代码模块,它们的目的都是为了代码重用,而多态则是为了实现另外一个目的:接口重用。多态类提供了相同的操作接口,但能适应于不同的应用要求。当基于父类所设计的程序在应用的时候需要适应子类操作变化时,就需要使用虚方法通知编译器这种可能的变化,使编译器为虚方法调用生成特别代码,以便运行时对虚方法调用采用动态绑定。

实现多态步骤

1)在父类中定义虚方法。如 Basepacket类中的虚方法 printB。
2)在子类中重写父类中的虚方法。如My_packet中对printB的重写。
3)申明父类对象的变量(如p1),该变量既可以指向父类对象 (如p1自身),也可以指向子类对象(如p2)。当变量指向父类对象时,调用的是父类方法;当变量指向子类对象时,调用的是子类同名方法。为此,当父类的对象指向不同的子类对象的时候,虚方法(如printB)可以表现出不同的实现方法,而它们都可以通过统一的父类对象实现访问。

  • 11
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

借问众神明.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值