繼承是基于類的面向?qū)ο?a href="http://www.xsypw.cn/v/tag/1315/" target="_blank">編程(object-oriented pro - gramming)的最重要特性之一。
擴(kuò)展類,簡(jiǎn)言之,就是基類的擴(kuò)展。
擴(kuò)展類繼承了基類的所有屬性和方法,并且支持在繼承類中重寫(xiě)基類的屬性和方法以及新增更多的屬性和方法。
所以,繼承類的好處是什么?
1、繼承類對(duì)基類的復(fù)用+改進(jìn)
2、基類的改動(dòng)能很快地影響到所有繼承類,減少公共代碼的修改
例如,可以定義一個(gè)名為EthernetPacket的基類。然后定義擴(kuò)展類,如EtherErrorPacket、EtherLatencyPacket等,除了繼承基類的屬性,還可以根據(jù)需要新增更多的新屬性和方法。
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個(gè)functions “bus”和“disp”
由于我們沒(méi)有顯式地定義構(gòu)造函數(shù)new(),所以變量data1, data2和busx都會(huì)被初始化成“x”態(tài) 。
class “ext”是class “base”的繼承類,所以類“ext”自然也會(huì)有屬性“data1,” “data2,” 和“busx”。
同時(shí)我們?cè)陬悺癳xt”中額外聲明了屬性“data3”,并且覆蓋了父類中函數(shù)“bus”和“disp”的聲明。
在上面的例子中,我們?cè)跀U(kuò)展類"ext"中的構(gòu)造函數(shù)中通過(guò)關(guān)鍵字“super.”來(lái)調(diào)用父類中聲明的函數(shù)。所以會(huì)打印:
From Base Class :: busx OR = xxxxxxxx
在initial語(yǔ)句塊中,我們賦值父類中的屬性,然后打印出“busx.”(即data1 | data2)。然后修改擴(kuò)展類中的屬性,然后打印出“busx.”(覆蓋過(guò)的函數(shù)data1 & data2 & data3)
仿真的log也證明了父類的函數(shù)被成功地覆蓋掉了。
每一個(gè)class 都會(huì)有一個(gè)構(gòu)造函數(shù)new()(隱式或者顯式的),在擴(kuò)展類的構(gòu)造函數(shù)中,第一件事就是要去調(diào)用父類的構(gòu)造函數(shù)“super.new( )”。然后如果你忘了在擴(kuò)展類的構(gòu)造函數(shù)中添加,編譯仿真工具也會(huì)自動(dòng)幫你添加的。
一般來(lái)說(shuō)不需要顯式地添加super.new(),但是如果構(gòu)造函數(shù)帶參數(shù),那么必須要顯式地添加supoer.new()
Inheritance Memory Allocation
還是那句話,理解一個(gè)語(yǔ)言的很多特性都需要從內(nèi)存分配的角度去理解。
如果需要完全理解擴(kuò)展類,就需要理解基類和擴(kuò)展類中的屬性和函數(shù)的內(nèi)存分配。
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
在上面的例子中,雖然我們只是調(diào)用了擴(kuò)展類的構(gòu)造函數(shù)“b = new( ),” ,但是實(shí)際上,我們不僅分配的類“bb”的內(nèi)存空間,還分配了基類“aa”的內(nèi)存空間,即使變量名稱一樣。
這個(gè)同名的變量需要通過(guò)作用域(不同的內(nèi)存分配)進(jìn)行區(qū)分。
審核編輯:湯梓紅
-
Verilog
+關(guān)注
關(guān)注
28文章
1351瀏覽量
110243 -
System
+關(guān)注
關(guān)注
0文章
165瀏覽量
37019
原文標(biāo)題:SystemVerilog中的類的繼承
文章出處:【微信號(hào):芯片驗(yàn)證工程師,微信公眾號(hào):芯片驗(yàn)證工程師】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論