尽管使用 Overridable/Overrides,实现 ToString 不会覆盖原始的 ToString 方法。我想念什么?
Implementing ToString does not override the original ToString method despite using Overridable/Overrides. What do I miss?
我想,VB 的 Overridable
和 Overrides
说明符并不像我想象的那样起作用。
其他 类 继承了 3 代:Grandfather
、Father
和 TestOverrides
。
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
。我想念什么?
如果通过接口调用就可以了:
Sub Main()
Dim oTest As IElements = New TestingOverrides("x")
Console.Write(oTest.ToString())
End Sub
但是,如果您通过 class 的类型调用它,那么您必须使用 class 的方法名称。因为,在 class 上,您将其声明为名为 IElements_ToString
的 public 方法,所以您必须这样调用它:
Sub Main()
Dim oTest As New TestingOverrides("x")
Console.Write(oTest.IElements_ToString())
End Sub
在 class 上调用 ToString
的唯一原因是因为所有 class 都从基础 public ToString
中继承了一个方法 Object
类型。如果您使用任何其他方法名称,它会告诉您指定的方法不存在。
正如其他人所提到的...由于所有类型都自动继承 ToString
方法,因此通过接口定义另一个具有相同名称的方法是不寻常的、意外的和令人困惑的。最好将其命名为 GetValue
或 GetDescription
之类的名称,或者简单地信任所有派生的 classes 来覆盖 Object.ToString
方法。如果你真的想强制所有派生的 classes 提供 ToString
实现,你可以通过 Grandfather
class:
的实现来强制它
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
我想,VB 的 Overridable
和 Overrides
说明符并不像我想象的那样起作用。
其他 类 继承了 3 代:Grandfather
、Father
和 TestOverrides
。
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
。我想念什么?
如果通过接口调用就可以了:
Sub Main()
Dim oTest As IElements = New TestingOverrides("x")
Console.Write(oTest.ToString())
End Sub
但是,如果您通过 class 的类型调用它,那么您必须使用 class 的方法名称。因为,在 class 上,您将其声明为名为 IElements_ToString
的 public 方法,所以您必须这样调用它:
Sub Main()
Dim oTest As New TestingOverrides("x")
Console.Write(oTest.IElements_ToString())
End Sub
在 class 上调用 ToString
的唯一原因是因为所有 class 都从基础 public ToString
中继承了一个方法 Object
类型。如果您使用任何其他方法名称,它会告诉您指定的方法不存在。
正如其他人所提到的...由于所有类型都自动继承 ToString
方法,因此通过接口定义另一个具有相同名称的方法是不寻常的、意外的和令人困惑的。最好将其命名为 GetValue
或 GetDescription
之类的名称,或者简单地信任所有派生的 classes 来覆盖 Object.ToString
方法。如果你真的想强制所有派生的 classes 提供 ToString
实现,你可以通过 Grandfather
class:
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