大李坐在轉椅上左右晃動著,手中的一個硬幣在他指間靈巧地翻滾著。 “hi, Henry。你對重寫與重載的意思理解是怎麼樣的呢?”
我正盯著他手中的硬幣發愣呢,“哦,重寫,就是您剛才舉的示例中,在派 生類中用Overrides重新編寫有Overridable標識的基類的方法或屬性;重載麼, 就是我們可以用同樣的名稱,在一個類中用不同的參數列表來創建多個方法和屬 性,在調用時就可以適應不同參數類型的要求。”
“在一個類 中創建?”大李的左眉向上一挑,我就知道我可能說錯了。但是,好象沒有 說錯什麼呀。
“那好,你看一下,這樣的寫法會有什麼結果?”
Public Class CBaseHenry Public Sub oldY() Console.WriteLine("基類的oldY方法") End Sub End Class Public Class CDerivedHenry Inherits CBaseHenry Public Overloads Sub oldY(ByVal j As Integer) Console.WriteLine("派生類的oldY方法") End Sub End Class Public Sub Main() Dim obj As CDerivedHenry = New CDerivedHenry()
然後大 李寫了obj.oldY這時出現的智能感知菜單上出現了參數列表:
“咦,第二個oldY()無參數過程簽名應該是基類定義的呀。為什 麼在派生類的實例中也會出現呀!”我不由好奇起來。
“沒錯 。還記得我上次曾顯式編寫構造函數的事嗎?我用了一個mybase.new()用於繼承 下基類的性質。現在沒有寫,其實是一種默認的隱式調用。”大李一說我就 明白了,其實現在的派生類應該是內含兩個oldY方法了,無參數的oldY()其實就 是基類的方法,是由於Overloads和Mybase.new()雙重作用的影響。
“那你再看這樣的變化情況。”大李象是看出我已經明白了這 個問題。他在派生類中添加了一個用Overloads標識的與基類形式一致的無參數 oldY()。
Public Class CBaseHenry Public Sub oldY() Console.WriteLine("基類的oldY方法") End Sub End Class Public Class CDerivedHenry Inherits CBaseHenry Public Overloads Sub oldY(ByVal j As Integer) Console.WriteLine("派生類的oldY方法1") End Sub Public Sub oldY() Console.WriteLine("派生類的oldY方法2") End Sub End Class Public Sub Main() Dim obj As CDerivedHenry = New CDerivedHenry() obj.oldY() End Sub
“好的,現在你再說說看,現在的obj.oldY()的運行 結果會打印出什麼?”大李手按在F5運行鍵上問我。
“應該是 派生類的,不對,基類,呃,派生類……”我一下子就暈了。
“呵呵。”大李也不禁發笑起來。然後點擊了一下F5鍵。結果 是:
派生類的oldY方法2
“這就叫隱藏,我們用 overloads方式,隱藏了基類的同名方法。以防用戶發生混淆。一般來說,隱藏有 兩種情況,一種是通過范圍來實現。比如你定義一個全局變量x,但在一個方法中 ,你又定義了一個局部變量x,在方法中使用x時,使用的是局部變量的那一個, 也就是用局部變量x在方法中隱藏了全局變量x。另一種情況,就是通過繼承來隱 藏,方法麼,除了剛才用的overloads,還可以用Shadows關鍵字來實現。 ”
“Shadows?陰影?倒是很貼切的名字。這個是怎麼用的呢 ?”我興趣由然而生。
“Shadows功能很強的。”說著, 大李又開始修改剛才的代碼了。
Public Class CBaseHenry Public Sub oldY() Console.WriteLine("基類的oldY方法") End Sub End Class Public Class CDerivedHenry Inherits CBaseHenry Public Shadows Sub oldY(ByVal j As Integer) Console.WriteLine("派生類的oldY方法") End Sub End Class Public Sub Main() Dim obj As CDerivedHenry = New CDerivedHenry()
再寫到 obj.oldY時,出現的智能感知菜單上就剩下一個方法了。
“哈,真的呢,基類的方法看不到了。但是,這和重寫的效果豈 不是一樣了嗎?”我不由地又想起一個問題,如果是一樣的作用,要 Shadows干什麼呀。
“還是有區別的。”大李開始扳著指頭數 起來,“最明顯的區別在於,隱藏適用於任何元素類型,你可以在派生類中 用Public Shadows oldY as Integer來隱藏基類的oldY()方法;而重寫只能適用 於方法與屬性,而且聲明參數與修飾符都要求完全一致。”
“ 還要注意一點,當派生類又派生出一個子類時,重寫與隱藏都會被繼承下去。當 然,如果在派生類中是用private來修飾Shadows成員的話,它的子類就會繼承它 基類的成員了。”
“我倒是感覺,現在VB.NET對繼承的處理功 能真的很強大,有繼承,對於編程者來說,真的是件好事。”我不由感歎道 。
“不錯,繼承層次體系是有很多好處,但是事物總是有其雙面性 ,繼承也有不少問題,其中最麻煩的,就是‘脆弱的基類’。” 大李緊鎖眉頭認真地說。
“哦,什麼叫‘脆弱的基類’ ?”我不解地問。