system verilog 多态 虚函数 virtual function $cast(son, father) 抽象类 virtual class

多态

实现多态有以下方法:虚函数、虚类、重载

多态的目的就是实现函数的重载,从而使得一个子类的指针在以父类的类型传递时,表现出的行为依然是子类的行为。


虚函数 virtual function:

  • 不使用 virtual,父类句柄虽指向子类对象,但调用的仍是父类本身的函数
  • 使用 virtual,父类句柄指向子类对象,调用的是子类的函数
// 不使用virtual,父类句柄虽指向子类对象,但调用的仍是父类本身的函数

class father;
	function display();
      $display("This is Father!!");
	endfunction
endclass

class son extends father;
	function display();
		$display("This is Son!!");
	endfunction
endclass

module tb;
	father	father_inst;
	son		son_inst;

	initial begin
		son_inst	= new();  // 子类对象
		father_inst	= son_inst;  // 父类指针指向子类
		father_inst.display();   // 父类指针依旧调用父类函数
		son_inst.display();
	end
endmodule

在这里插入图片描述

// 使用virtual,父类句柄指向子类对象,调用的是子类的函数

class father;
	virtual function display();  // 父类定义函数为virtual,其子类同名函数默认为virtual 
      $display("This is Father!!");
	endfunction
endclass

class son extends father;
	function display();  // 父类定义函数为virtual,其子类同名函数默认为virtual 
		$display("This is Son!!");
	endfunction
endclass

module tb;
	father		father_inst;
	son			son_inst;

	initial begin
		son_inst	= new();   // 子类对象
		father_inst	= son_inst; // 父类指针指向子类
		father_inst.display();  // 父类指针调用子类函数
		son_inst.display();   
	end
endmodule

在这里插入图片描述

  • 声明 virtual function 时,根据对象来决定调用
  • 未声明 virtual function 时,根据句柄来决定调用

class bird;
  virtual function void hungry();  // 父类virtual函数
    $display("father virtual function");
  endfunction
  function void hungry2();
  	$display("father function");
  endfunction
endclass
    
class parrot extends bird;
  function void hungry();  // 子类函数与父类virtual函数同名,默认为virtual
    $display("son virtual function");
  endfunction
  function void hungry2();
    $display("son function");
  endfunction
endclass

module tb;
  bird A;
  parrot B;
  initial begin
    A = new();
    B = new();
    A = B;   // 父类指针指向子类 (父类可以指向子类,因为父类有的对象和函数,子类都有)
    A.hungry();   // 父类指针指向子类,子类函数与父类virtual函数同名情况下, 父类指针指向子类函数 
    A.hungry2();  // 子类函数与父类函数同名,但父类函数不是virtual, 父类指针不可以指向子类函数 
    B.hungry();   
    B.hungry2();
  end

endmodule

在这里插入图片描述

在这里插入图片描述


$cast:子类指向父类

  • 子类指针指向 指向子类的父类指针 (其实还是子类指向子类)
$cast(B,A)

在这里插入图片描述


class bird;
  virtual function void hungry();  // 父类virtual函数
    $display("father virtual function");
  endfunction
  function void hungry2();
  	$display("father function");
  endfunction
endclass
    
class parrot extends bird;
  function void hungry();  // 子类函数与父类virtual函数同名,默认为virtual
    $display("son virtual function");
  endfunction
  function void hungry2();
    $display("son function");
  endfunction
endclass

module tb;
  bird A;
  parrot B;
  initial begin
    A = new();
    B = new();
    A = B;   // 父类指针指向子类
    if(!$cast(B,A))begin   // 子类指针B指向 指向子类的父类指针A (其实还是子类指向子类)
      $display("B = A; failed");
    end
    else begin
      $display("B = A; OK !!!!");  // 这种$cast是合法的,效果同直接
    end 
    A.hungry();  // 父类指针指向子类,子类函数与父类virtual函数同名情况下, 父类指针指向子类函数 
    A.hungry2(); // 父类指针指向子类,子类函数与父类函数同名,但父类函数不是virtual, 父类指针仍然指向父类函数
    B.hungry();   // 子类指针B指向 指向子类的父类指针A (B绕了一圈指向自己)
    B.hungry2();
  end

endmodule

在这里插入图片描述

  • 子类指针指向 指向孙类的父类指针 (其实还是子类指向孙类)

在这里插入图片描述

$cast(B,A)
class bird;
  virtual function void hungry();  // 父类virtual函数
    $display("father virtual function");
  endfunction
  function void hungry2();
  	$display("father function");
  endfunction
endclass
    
class parrot extends bird;
  function void hungry();  // 子类函数与父类virtual函数同名,默认为virtual
    $display("son virtual function");
  endfunction
  function void hungry2();
    $display("son function");
  endfunction
endclass

class dog extends parrot;
  function void hungry();
    $display("grandson virtual function");
  endfunction
  function void hungry2();
    $display("grandson function");
  endfunction
endclass

module tb;
  bird A;
  parrot B;
  dog C;
  initial begin
    A = new();
    B = new();
    C = new();
    A = C;
    if(!$cast(B,A))begin
      $display("B = A; failed");
    end
    else begin
      $display("B = A; OK !!!!");
    end
    A.hungry();  // 父类指向孙类,函数为virtual,父类指针调用孙类同名函数
    A.hungry2(); // 父类指向孙类,函数不是virtual,父类指针调用父类函数
    B.hungry();  // 子类指向 指向孙类的父类指针,函数是virtual,子类指针调用孙类同名函数
    B.hungry2(); // 子类指向 指向孙类的父类指针,函数不是virtual,子类指针调用子类函数
  end

endmodule

在这里插入图片描述


抽象类 virtual class:

  • virtual class (抽象类):可以被扩展但是不能被直接例化
  • 由抽象类扩展而来的类,只有在所以 pure virtual 纯虚方法都有实体的时候才能被例化。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值