尽管使用Overridable / Overrides,实现ToString不会覆盖原始的ToString方法。我想念什么?

时间:2019-06-17 14:32:19

标签: .net vb.net inheritance overriding

我猜想,VB的OverridableOverrides指示符不符合我的想法。

其他类继承自3代:GrandfatherFatherTestOverrides

Public Interface IElements
    Function ToString() As String
End Interface

Public Class Grandfather
    Implements IElements
    Private _MyArg As String
    Public Sub New(Arg As String)
        _MyArg = Arg
    End Sub
    Public Overridable Function IElements_ToString() As String _
        Implements IElements.ToString
        Return _MyArg
    End Function
End Class

Public Class Father
    Inherits Grandfather
    Implements IElements
    Public Sub New(Arg As String)
        MyBase.New(Arg)
    End Sub
    Public Overrides Function IElements_ToString() As String _
        Implements IElements.ToString
        Return MyBase.ToString
    End Function
End Class

Public Class TestingOverrides
    Inherits Father
    Implements IElements
    Public Sub New(Arg As String)
        MyBase.New(Arg)
    End Sub
    Public Overrides Function IElements_ToString() As String _
        Implements IElements.ToString
        Return MyBase.ToString
    End Function
End Class

他们的构造函数用于将值存储在私有属性中,其(重写的)ToString方法(作为接口方法实现)尝试检索该值。

Module Module1
    Sub Main()
        Dim oTest = New TestingOverrides("x")
        Console.Write(oTest.ToString)
        'produces: SSML.TestingOverrides. Why not "x"?
    End Sub
End Module

但是,调试器甚至没有输入oTest.ToString。我想念什么?

1 个答案:

答案 0 :(得分:2)

如果通过界面调用它,它将起作用:

Sub Main()
    Dim oTest As IElements = New TestingOverrides("x")
    Console.Write(oTest.ToString())
End Sub

但是,如果通过类的类型调用它,则必须使用该类的名称作为方法。由于在类上,您将其声明为名为IElements_ToString的公共方法,因此必须调用它:

Sub Main()
    Dim oTest As New TestingOverrides("x")
    Console.Write(oTest.IElements_ToString())
End Sub

在类上调用ToString完全有效的唯一原因是,因为所有类都固有于基础ToString类型的公共Object方法。如果您使用了其他方法名称,它会告诉您该命名方法不存在。

正如其他人所提到的...由于所有类型都会自动继承ToString方法,因此通过接口定义另一个具有相同名称的方法是不寻常,意外的且令人困惑的。最好将其命名为GetValueGetDescription,或者简单地信任所有派生类以覆盖Object.ToString方法。如果您确实要强制所有派生类提供ToString实现,则可以通过实现Grandfather类来实现它:

Public Class Grandfather
    Implements IElements
    Private _MyArg As String
    Public Sub New(Arg As String)
        _MyArg = Arg
    End Sub
    Public NotOverridable Overrides Function ToString() As String _
        Implements IElements.GetArg
        Return _MyArg
    End Function
End Class

或者:

Public Class Grandfather
    Implements IElements
    Public NotOverridable Overrides Function ToString() As String 
        Return GetArg()
    End Function

    Public MustOverride Function GetArg() Implements IElements.GetArg
End Class