繼承是基于類的面向對象編程(object-oriented pro - gramming)的最重要特性之一。
擴展類,簡言之,就是基類的擴展。
擴展類繼承了基類的所有屬性和方法,并且支持在繼承類中重寫基類的屬性和方法以及新增更多的屬性和方法。
所以,繼承類的好處是什么?
1、繼承類對基類的復用+改進
2、基類的改動能很快地影響到所有繼承類,減少公共代碼的修改
例如,可以定義一個名為EthernetPacket的基類。然后定義擴展類,如EtherErrorPacket、EtherLatencyPacket等,除了繼承基類的屬性,還可以根據需要新增更多的新屬性和方法。
module class_TOP( ); class base; logic [31:0] data1; logic [31:0] data2; logic [31:0] busx; function void bus; busx = data1 | data2; endfunction function void disp; $display("From Base Class :: busx OR = %h", busx); endfunction endclass : base class ext extends base; logic [31:0] data3; //add a new property function new ( ); $display("Call base class method from extended class - super.disp"); super.disp; endfunction function void bus; //redefne function 'bus' of class 'base' busx = data1 & data2 & data3; //data1,data2 inherited from class 'base' endfunction function void disp; //redefne function 'disp' of class 'base' $display("From Extended Class :: busx AND = %h",busx); endfunction endclass : ext initial begin base b1; ext e1; b1 = new; e1 = new; b1.data1 = 32'h ffff_0000; b1.data2 = 32'h 0000_ffff; b1.bus; b1.disp( ); e1.data1 = 32'h 0101_1111; e1.data2 = 32'h 1111_ff; e1.data3 = 32'h 1010_1010; e1.bus; e1.disp( ); end endmodule
仿真log:
Call base class method from extended class - super.disp From Base Class :: busx OR = xxxxxxxx From Base Class :: busx OR = ffffffff From Extended Class :: busx AND = 00001010 V C S S i m u l a t i o n R e p o r t
在class “base”中,我們定義了屬性data1、 data2和busx,然后又定義了2個functions “bus”和“disp”
由于我們沒有顯式地定義構造函數new(),所以變量data1, data2和busx都會被初始化成“x”態 。
class “ext”是class “base”的繼承類,所以類“ext”自然也會有屬性“data1,” “data2,” 和“busx”。
同時我們在類“ext”中額外聲明了屬性“data3”,并且覆蓋了父類中函數“bus”和“disp”的聲明。
在上面的例子中,我們在擴展類"ext"中的構造函數中通過關鍵字“super.”來調用父類中聲明的函數。所以會打印:
From Base Class :: busx OR = xxxxxxxx
在initial語句塊中,我們賦值父類中的屬性,然后打印出“busx.”(即data1 | data2)。然后修改擴展類中的屬性,然后打印出“busx.”(覆蓋過的函數data1 & data2 & data3)
仿真的log也證明了父類的函數被成功地覆蓋掉了。
每一個class 都會有一個構造函數new()(隱式或者顯式的),在擴展類的構造函數中,第一件事就是要去調用父類的構造函數“super.new( )”。然后如果你忘了在擴展類的構造函數中添加,編譯仿真工具也會自動幫你添加的。
一般來說不需要顯式地添加super.new(),但是如果構造函數帶參數,那么必須要顯式地添加supoer.new()
Inheritance Memory Allocation
還是那句話,理解一個語言的很多特性都需要從內存分配的角度去理解。
如果需要完全理解擴展類,就需要理解基類和擴展類中的屬性和函數的內存分配。
module class_TOP( ); class aa; int i1; function funAA; endfunction endclass : aa class bb extends aa; int i1; function funBB; endfunction endclass : bb initial begin bb b; b = new( ); end endmodule
在上面的例子中,雖然我們只是調用了擴展類的構造函數“b = new( ),” ,但是實際上,我們不僅分配的類“bb”的內存空間,還分配了基類“aa”的內存空間,即使變量名稱一樣。
這個同名的變量需要通過作用域(不同的內存分配)進行區分。
審核編輯:湯梓紅
-
Verilog
+關注
關注
28文章
1351瀏覽量
110075 -
System
+關注
關注
0文章
165瀏覽量
36929
原文標題:SystemVerilog中的類的繼承
文章出處:【微信號:芯片驗證工程師,微信公眾號:芯片驗證工程師】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論