標籤:
我在上篇文章中講解了類 的繼承和重寫,如果想要在衍生類別中重寫基類了方法或函數,那首先基類必須要有用 Overridable 關鍵字的公開聲明的方法或函數,這樣,基類的衍生類別才能用 Overrides 關鍵字來重寫基類帶有 Overridable 關鍵字的公開方法或函數。
重載是什麼意思呢?
重載(Overloads): 就是我們可以用同樣的名稱,在衍生類別中用不同的參數列表來建立多個方法和屬性,在調用時就可以適應不同參數類型的要求。
呵呵...那好,我們來看一下,這樣的寫法會有什麼結果:
Module Module1
Public Class baseClass
Public Function CountY() As Integer
CountY = 100
End Function
End Class
Private Class derivedClass
Inherits baseClass
Public Overloads Function CountY(ByVal i As Integer) As Integer
CountY = i * 2
End Function
End Class
End Module
好!基類和衍生類別寫好了,衍生類別中也重載了基類的 ConutY 函數,那我們就來執行個體化衍生類別,並使用它的函數看看什麼情況:
呵呵,看到了吧,居然有兩個 CountY 函數,一個無參數的和一個有參數的!!為什麼會這樣呢?基類的無參數 CountY 函數怎麼會出現在衍生類別的對象中?
沒錯 ,我在類的繼承和重寫的文章中講到,衍生類別具有繼承基類所以公用成員的能力,你再看基類的 CountY 函數,發現了吧,它用的是Public 關鍵字聲明的,這是公開性的函數。所以...
另外:還記得上篇文章也介紹“顯式編寫建構函式 New 的事” ,我用了一個 mybase.new() 繼承了基類的性質。現在沒有寫,其實是一種預設的隱式調用。
所以現在的衍生類別應該是內含兩個 CountY 函數了,無參數的 CountY 其實就是基類的方法,是由於 Overloads 和 Mybase.new() 雙重作用的影響。
那再看這樣的變化情況。我們在衍生類別中添加一個用 Overloads 標識的與基類形式一致的無參數 CountY 後,再執行會出現什麼情況:
Module Module1
Public Class baseClass
Public Function CountY() As Integer
CountY = 100
End Function
End Class
Private Class derivedClass
Inherits baseClass
Public Overloads Function CountY(ByVal i As Integer) As Integer
CountY = i * 2
End Function
Public Overloads Function CountY() As Integer
CountY = 200
End Function
End Class
Sub main()
Dim obj As New derivedClass
Console.WriteLine("帶參數的 CountY 函數的傳回值為:{0} ", obj.CountY(10))
Console.WriteLine("無參數的 CountY 函數的傳回值為:{0} ", obj.CountY())
Console.Read()
End Sub
End Module
我們來看看結果:
怎麼樣,是不是很好奇,為什麼是執行的衍生類別中的無參數函數 CountY ,而不是執行的基類中的無參數函數 CountY ?
其實這就叫隱藏(Shadows)!
我們用 Overloads 重載方式隱藏了基類的同名方法,以防使用者發生混淆。
一般來說,隱藏有兩種情況:一種是通過範圍來實現。比如你定義一個全域變數 x,但在一個方法中 ,你又定義了一個局部變數 x,在方法中使用 x 時,使用的是局部變數的那一個, 也就是局部變數 x 在方法中隱藏了全域變數x(這裡牽涉到範圍的概念,所以這個比如不是很恰當);另一種情況,就是通過繼承來隱藏。方法麼,除了剛才用的 overloads,還可以用 Shadows 關鍵字來實現。
Shadows(遮蔽、陰影),倒是很貼切的名字。
Shadows功能很強的。
Private Class derivedClass
Inherits baseClass
Public Shadows Function CountY(ByVal i As Integer) As Integer
CountY = i * 2
End Function
End Class
好了,我們用 Shadows 關鍵字代替 Overloads 來實現重載後,看看會出現幾個 CountY 函數:
看到了吧,只有一個了!
我們看運行結果:
Sub main()
Dim obj As New derivedClass
Console.WriteLine("帶參數的 CountY 函數的傳回值為:{0}", obj.CountY(50))
End Sub
“哈,真的呢,基類的方法看不到了。但是,這和重寫的效果豈 不是一樣了嗎?”我不由地又想起一個問題,如果是一樣的作用,要 Shadows幹什麼呀。
“還是有區別的。”大李開始扳著指頭數 起來,“最明顯的區別在於,隱藏適用於任何元素類型,你可以在衍生類別中 用Public Shadows oldY as Integer來隱藏基類的oldY()方法;而重寫只能適用 於方法與屬性,而且聲明參數與修飾符都要求完全一致。”
“ 還要注意一點,當衍生類別又派生出一個子類時,重寫與隱藏都會被繼承下去。當 然,如果在衍生類別中是用private來修飾Shadows成員的話,它的子類就會繼承它 基類的成員了。”
“我倒是感覺,現在VB.NET對繼承的處理功 能真的很強大,有繼承,對於編程者來說,真的是件好事。”我不由感歎道 。
“不錯,繼承層次體系是有很多好處,但是事物總是有其雙面性 ,繼承也有不少問題,其中最麻煩的,就是‘脆弱的基類’。” 大李緊鎖眉頭認真地說。
“哦,什麼叫‘脆弱的基類’ ?”我不解地問。
類 的重載(Overloads)與隱藏(Shadows)