sv中多态/虚方法的用法,通过$cast动态类型转换实现父类句柄和子类句柄的转化的注意事项

** 子类句柄仅可以指向子类对象,不可以指向父类对象 **

** 父类句柄可以指向父类对象,同时也可以指向子类对象,但是仅可以访问子类对象中的父类变量和方法 **

通过一个例子来理解类的多态,以及虚方法的使用: 

1.首先定义一个基类 donkey,并根据该基类派生一个子类baby_donkey;

父类donkey 中实现两个方法,分别为 information( ) 和 favourite_food( ), 其中第二个方法被定义为虚方法。子类baby_donkey实现两个同名方法,如代码所示:

class donkey;

	string 	color = "White";
	int		weight = 150;
	int		price = 500;

	task information();
		$display("@@ This is the father donkey, color is %s, weight = %0d @@", this.color, this.weight);
	endtask

	virtual task favourite_food(input string food);
		$display("@@ Father donkey loves %s @@", food);
	endtask

endclass

//----------------------------------------------------------------------------------------
class baby_donkey extends donkey;

	string	color = "Black";
	int		weight = 130;
	int		price = 250;

	task information();
		$display("@@ This is the baby donkey, colocr is %s, weight = %0d @@", this.color, this.weight);
	endtask

	virtual task favourite_food(input string food);
		$display("@@ Baby donkey loves %s @@", food);
	endtask

endclass

2.  声明父类句柄 dk,dk1;为父类donkey开辟空间,将句柄dk1指向该对象。

     声明子类句柄 b_dk,b_dk1,b_dk2;为子类开辟空间,将句柄b_dk指向该对象。

	donkey		dk, dk1;
	baby_donkey	b_dk, b_dk1, b_dk2;
		
	b_dk = new();
	dk1 = new();

【情况一】 将子类句柄直接赋值给父类句柄

将子类句柄传递给父类句柄,父类句柄指向该子类句柄所指向的对象;

通过父类句柄调用同名非虚方法时,父类中的方法会被调用;调用虚方法时,则会根据句柄指向的对象类型调用相应的方法。虚方法的调用与句柄类型无关,仅与句柄指向的类型有关。

module tb;

	initial begin
		
		string		food = "Grass";

		donkey		dk, dk1;
		baby_donkey	b_dk, b_dk1, b_dk2;
		
		b_dk = new();
		dk1 = new();

		//basic class handle point to child class object by passing the child handle to         
          parent class	

		dk = b_dk;

		dk.information();		 //parent handle call non-virtual method
		dk.favourite_food(food); //parent handle call virtual method

		b_dk.information();		   //child handle call non-virtual method
		b_dk.favourite_food(food); //parent handle call virtual method

		$display("@@ Baby Price: %0d @@", b_dk.price);
		$display("@@ Parent Price: %0d @@", dk.price);
@@ This is the father donkey, color is White, weight = 150 @@
@@ Baby donkey loves Grass @@
@@ This is the baby donkey, colocr is Black, weight = 130 @@
@@ Baby donkey loves Grass @@
@@ Baby Price: 250 @@
@@ Parent Price: 500 @@

【情况二】 通过 $cast 动态转换,将父类句柄转换为子类句柄

通过 $cast 动态转换父类句柄到子类句柄的转换,首先要确保该父类句柄所指向的对象是目标子类句柄类型的对象;如果父类句柄指向的是父类对象,则不能通过动态转换的方式完成句柄类型的转换,因为子类句柄指向父类对象是非法的。

	//parent class handle point to child class object, $cast the parent handle to child 
      handle
		
		$cast(b_dk1, dk);

		//parent handle already point to child object, so it's legal to $cast the parent handle to child handle
		//now b_dk1, b_dk, dk point to the same object which is allocated by: baby_donkey b_dk = new();

		b_dk1.information();
		b_dk1.favourite_food(food);
@@ This is the baby donkey, colocr is Black, weight = 130 @@
@@ Baby donkey loves Grass @@

【情况三】 错误的句柄类型转换,父类句柄直接赋值给子类句柄

父类句柄指向父类对象,通过 $cast 将父类句柄转换为子类句柄会失败;

直接将父类句柄赋值给子类句柄同样是非法操作。

将父类句柄dk1复制给父类句柄dk,原来指向子类对象的父类句柄dk不再指向子类对象,而指向dk1所开辟的父类对象空间。

//parent class handle point to parent class object, illegal to $cast the parent handle to child handle 
    b_dk2 = dk1; // illegal 
    $cast(b_dk2, dk1); // illegal since parent handle dk1 points to the parent object
		
	dk = dk1;

	dk.information();
	dk.favourite_food(food);
@@ This is the father donkey, color is White, weight = 150 @@
@@ Father donkey loves Grass @@

  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值