1. 程式人生 > >解讀 .NET 中的重寫與過載

解讀 .NET 中的重寫與過載

很多人對“重寫”和“過載”這兩個概念都很模糊,甚至把它們弄混淆。我們都知道,面嚮物件語言的四大特徵是:抽象、封裝、繼承和多型。而重寫和過載是多型的兩種表現形式。多型,顧名思義,就是指多種形態。而重寫和過載正好體現了這一點。現在我們以 VB.NET 語言來說明兩者的區別。


        重寫是發生在父類與子類之間的關係。具體來講就是子類可以重寫父類的現有的方法。它要求子類的方法名稱及引數必須與父類完全一致。比如吃飯,父親可以吃兩碗麵,孩子同樣也是吃麵,卻只能吃一碗。

        過載則主要是發生在同一個類當中的,它通過多個名稱相同的方法,但方法引數不相同,或者方法返回型別不相同來加以區別。其中,方法引數不相同包括以下幾種情況:引數的個數不相同,引數的型別不相同,引數的對應位置不相同。需要說明的是,過載同樣可以應用到父類與子類當中。即子類過載了父類的方法。

重寫:

        在 VB.NET 中,重寫汲及到的關鍵字有:
                OverRidable: 在父類中宣告的可以在子類中重寫的方法。
                OverRides: 在子類中宣告的要重寫父親中可重寫的方法。
                MustOverRide: 在父類中,表示這個方法必須在子類中重寫。此時,該類必須宣告為抽象類。
                NotOverridable: 如果當前類還有子類,那麼,在其子類中,該方法不允許被重寫。

        下面通過一個例子來認識它們的作用。


'本例中我們聲明瞭三個類,分別代表三種物件:人,父親,兒子。兒子繼承自父親,父親又繼承自人。

'宣告一個抽像類
Public MustInherit Class People
    '它包括一個抽象方法,這個方法必須要在其子類中被實現(重寫)
    Public MustOverride Sub Eat(ByVal FoodName As String, ByVal num As Integer)
End Class

'宣告父親類,繼承自 Person 類
Public Class Father : Inherits People
   '重寫 Person 的抽象方法,這是必須的。

    Public Overrides Sub Eat(ByVal FoodName As String, ByVal num As Integer)
        Console.WriteLine("父親吃{0},他可以吃{1}碗!", FoodName, num)
    End Sub

    '宣告一個可被重寫的函式,用 OverRidable 關鍵字
    Public Overridable Function GetMyName() As String
        Return "父親"
    End Function

    '宣告另外一個方法,用來說明子類中使用 NotOverRidable


    Public Overridable Sub ShowMyFatherClass()
        Console.WriteLine("我的父類是 People")
    End Sub
End Class

'宣告兒子類,繼承自 Father
Public Class Son : Inherits Father

    '子類重寫 Father 類的 Eat 方法,這裡有兩點要說明:
    '1. Son 類作為 People 子類(Father)的子類,它不必一定要重寫抽象方法。
    '     換句話說,抽象類的抽象方法,只需要在其直接子類中強制實現,而不用
    '     在它的除直接子類之外的其它子類(可看作是“孫類”)中實現。

    '2. 在 Father 類中的 Eat 方法標記為 OverRides,它包括了兩層含義:(1).它重寫
    '     了抽象父類中的抽象方法; (2). 這個方法可以在其子類中被隱式重寫。因此,
    '      它不包括 OverRidable 這個關鍵字,而其子類 Son 就可以對這個方法重寫

    Public Overrides Sub Eat(ByVal FoodName As String, ByVal num As Integer)
        Console.WriteLine("孩子吃{0},他能吃{1}碗!", FoodName, num)
    End Sub

    '重寫父類中被宣告為 OverRidable 的方法,重寫時用關鍵字 OverRides
    Public Overrides Function GetMyName() As String
        '如果要使用父類的實現過程,則使用 MyBase 關鍵字
        'Return MyBase.GetMyName()

        Return "孩子"
    End Function

    '如果 Son 類還有子類,那麼下面這個方法不可以在其子類中被重寫,因為它被宣告
    '為 NotOverridable。這裡有一點要注意:
    '如果一個方法被宣告為 NotOverRidable,那麼它也同時必須被宣告為 OverRides

    Public NotOverridable Overrides Sub ShowMyFatherClass()
        Console.WriteLine("我的父類是 Father")
    End Sub
End Class

過載:


        在 VB.NET 中,過載用到的關鍵是 OverLoads。請看如下程式碼:

    Public Sub ShowMySelf(ByVal Name As String)

    Public Sub ShowMySelf(ByVal Name As String, ByVal Age As Integer)
    Public Sub ShowMySelf(ByVal Name As String, ByVal Age As Integer, ByVal Sex As String)

Public Overloads Function GetMyInfo() As String

    Public Overloads Function GetMyInfo(ByVal MyID As Integer) As String

        這裡需要說明幾點:

        1. 對於在同一類當中,一組名稱相同的方法或函式過載時,可以加關鍵字 OverLoads 或者不加。但如果其中有一個方法加上,那同組其它方法也必須加該關鍵字。

        2. 如果該方法是過載父類中的方法。那麼必須加 OverLoads 關鍵字。

        3. 如果兩個同名函式僅返回型別不相同,則它們不能過載,即必須在引數上有所不同。