VB.NET之旅(四)—類和構造。本站提示廣大學習愛好者:(VB.NET之旅(四)—類和構造)文章只能為提供參考,不一定能成為您想要的結果。以下是VB.NET之旅(四)—類和構造正文
剛下班,就被大李找去了。“Henry,昨天對窗體的操作給你最大的領會 是什麼?”
“當然有領會,最深的印象就是VB.NET中類是無所 不在了,連窗體都成為了一個類。”我深有感受地說。
“沒錯 ,類是我們用來結構VB.NET使用順序時的最根本的編程構造了。你也學習過最基 本的面向對象編程了,那麼你能通知我,構造與類有什麼類似之處與不同之處嗎 ?”
“好的。”我口中答復著,心裡還是有點不以為然 ,“構造和類,都是對成員的封裝方式,但是類可以支持承繼 ……”
大李一邊點著頭,一邊聽我說,聽到我最後支 吾著沒了聲響才抬起頭“還有呢?”
“沒了。”我 這時才開端心中發慌。
“呵呵,相反之處我想你心中還是明白的, 它們都含有成員,包括結構函數、辦法、屬性、字段、常量、枚舉和事情。都可 以完成接口,都有共享的結構函數。”
“對不起,最後那一句 ,都有結構函數是什麼意思?構造的結構函數我歷來沒有自己定義過。 ”
大李立即寫下了這一段代碼:
Structure SHenry Public x, y As Integer Public Sub New(ByVal x As Integer, ByVal y As Integer) Me.x = x Me.y = y End Sub End Structure Sub main() Dim H1 As SHenry = New SHenry() Dim H2 As SHenry = New SHenry(2, 1) End Sub
“真的呢,可以完成構造的結構函數!”我還不斷 沒有留意過這個問題。“可是,你只定義過一個帶參數的結構函數,H2的實 例化我是明白的,可是H1怎樣也能經過編譯器檢測呢?”其實我心中更想問 的是構造怎樣也能實例化成對象,那和類真的很象呀。
“緣由麼, ”大李推了推眼鏡,“每個構造都隱式地具有 Public 無參數實例構 造函數,該結構函數發生構造的默許值。所以你平常不寫結構函數,也一樣可以 New出一個構造來,對吧?現實上,我們反而在構造類型聲明中不能夠聲明無參數 實例結構函數。只能聲明‘參數化’實例結構函數。 ”
“都可以用new來實例化,構造和類在內存分配上難道也是 一樣的嗎?”這個問題我不斷挺不明白,正好借這個話題問一下。
“在這下面,差異可就大了。”看到大李喜笑顏開的樣子,我 就知道問到點子上了,立即擺開架勢,作仔細傾聽狀。
“復雜來說 ,構造是值類型,而類是援用類型。因而,構造運用堆棧分配,類運用堆分配。 ”
看到我迷茫的雙眼,大李笑了笑,在電腦上飛快地寫了個示例:
Class CHenry Public z As Integer = 0 ‘能對非靜態成員初始化也是一個區別 End Class Sub main() Dim H1 As SHenry = New SHenry(0, 2) '賦給H1.x=0 Dim H2 As SHenry = H1 H2.x = 26 Dim R1 As New CHenry() 'R1.z也是等於0 Dim R2 As CHenry = R1 R2.z = 26 Console.WriteLine("H1.x=" &H1.x&",H2.x="& H2.x) Console.WriteLine("R1.z= "&R1.z&",R2.value= "& R2.z) End Sub
“你看一下後果應該是什麼?”大李一邊說,一邊 運轉了順序:
H1.x= 0, H2.x= 26 R1.z= 26, R2.value= 26
大李看著我瞪圓的雙眼,漸漸地說: “這就是值類型和援用類型的差異。構造的實例 H2.x 賦值並不影響H1.x, 這是由於雖然它們同屬於一種SHenry構造,但它們都有各自的存儲空間。相反, 給 R2.z賦值26後; 則會影響R1 和 R2 都援用的對象”
“說得 更清楚一點,類作為援用類型,是存儲在運轉時的堆上,只能經過援用該存儲來 訪問它們,不能直接訪問。援用類型的變量總是包括該類型的值援用,或包括空 援用。空援用不援用任何內容;除分配空援用外,對空援用停止的任何操作都是 有效的。援用類型的變量賦值只會創立援用的一個正本,而不是所援用的值的副 本。它們實踐上都是會指向同一塊存儲區的。”大李手指了指運轉的後果。
“構造是直接存儲在堆棧上,要麼在數組中,要麼在另一個類型中 。當包括構造實例的地位被銷毀時,構造實例也會被銷毀。值類型總是可以直接 訪問。我們不能創立對值類型的援用,也不能援用已銷毀的值類型實例。值類型 的變量總是包括此類型的值。與援用類型不同,值類型的值不能為空援用,也不 能援用派生相遠程度較大的類型的對象。值類型的變量賦值會創立所賦的值的副 本,當然會新開拓一塊內存區來保管值。”
“哦,我明白了。 它們還有什麼區別沒有?”我對構造和類的區別第一次有了深入的覺得。
“當然有很多,比方一切的構造成員都默許為 Public,類變量和常 量默許為 Private,其他的類成員默許為 Public;構造成員不能聲明為 Protected,類成員可以;構造進程不能處置事情,類進程可以;構造變量聲明不 能指定初始值、New 關鍵字或數組初始大小,類變量聲明可以。”大李喝了 口水,停了一下,然後持續說。
“構造從不終止,所以公共言語運 行庫從不在任何構造上調用 Finalize 辦法;類可由渣滓回收器終止,渣滓回收 器會跟蹤未完成的援用直到某個特定的實例,當檢測到沒有剩下的活動援用時, 渣滓回收器將在類上調用 Finalize。”
“這個我可以了解, 由於構造是值類型,是由零碎一致管理內存,不是援用,所以不會對內存形成危 害。”我接著說了兩句。
“還有,你方才也提到了它們之間一 個很重要的區別:構造是不可承繼的,而類可以承繼。其實構造本身是從 ValueType 類隱式承繼上去的。數據類型可分為值類型和援用類型。值類型要麼 是堆棧分配的,要麼是在構造中以內聯方式分配的。援用類型是堆分配的。援用 類型和值類型都是從最終的基類 Object 派生出來的。當值類型需求充任對象時 ,就在堆上分配一個包裝,該包裝能使值類型看上去像援用對象一樣,並且將該 值類型的值復制給它。該包裝被加上標志,以便零碎知道它包括一個值類型。這 個進程稱為裝箱,其反向進程稱為取消裝箱。裝箱和取消裝箱可以使任何類型像 對象一樣停止處置。”
“哦,我明白為什麼構造也能被實例化 成對象了!”我心中喜不自禁。“類的承繼我在用C++和Java時也常常 運用,但是VB6是不支持承繼的,上次您提到VB.NET可以支持承繼了,它是怎樣做 到的呀!”