How does “Overloads” work in a child class?

2019-07-01 14:42发布

问题:

I have a base class and a child class and they both have the same property and I don't understand why VB wants me to use "Overloads" for the property in the child class. The difference is the child class version of the property is Shared while the parent class is basically there for structure. The properties look like this:

Public MustInherit Class Parent
    Public ReadOnly Property Species As String
        Get
            Return "Should get species from a child." 
        End Get
    End Property
End Class

Public Class Child
    Inherits Parent
    Public Shared ReadOnly Property Species As String
        Get
            Return "Species1"
        End Get
    End Property
End Class

Species is flagged in the line Public Shared ReadOnly Property Species As String in the child class with the warning message

property 'Species' shadows an overloadable member declared in the base class 'Parent'. If you want to overload the base method, this method must be declared 'Overloads'.

What I want to know is why does it want this to be overloaded? Overloading is typically used when different parameters are being passed into functions with the same name which is well documented, but I've found nothing explaining why overloads is suddenly suggested in a situation like this.

Note: that the code properly reports "Species1" regardless of if have the "Overloads" or not adding to my confusion of what it actually does...

回答1:

If you want to overload the base method, this method must be declared 'Overloads'.

The error message is too generic. Note how it talks about a method even though the warning is about a property. You cannot overload a property.

If I were the King of France, I would have written the error message like:

Property 'Species' hides the 'Species' property inherited from the 'Parent' base class. Use the Shadows keyword to suppress this warning if hiding was intended. Change the name of the property if hiding was not intended.

This warning should almost never be ignored because is almost always identifies a code smell. Using the Shared keyword for Child.Species is very strange and almost certainly not what you intended. Any code that uses your Child object through a reference of type Parent will always get the wrong species name since it will use the base property. The more sane thing to do here is to declare the Parent.Species property Overridable and use the Overrides keyword in Child.Species property declaration, without Shared.



回答2:

If you shadow a member - the base class will still use it's version of the member when called. For example, if a function in your base class called Species it would still get the value "Should get species from a child."

In this case, overloading will cause functions in the base class to use the child's value.

To make this a bit clearer... the following code's message box says "Original Value", not "New Value"

    Public Class Form1
        Dim X As New Child
        Dim Y = MsgBox(X.ShowMe)
    End Class

    Public Class Parent

        Public Function ShowMe() As String
            Return member
        End Function

        Public Property member As String = "Original value"

    End Class

    Public Class Child
        Inherits Parent

        Public Property member As String = "New value"

    End Class