8

考虑以下代表排序系统的类:

Public Class OrderBase
    Public MustOverride Property OrderItem as OrderItemBase
End Class

Public Class OrderItemBase
End Class

现在,假设我们想将这些类扩展为一组更具体的订单类,同时保持 OrderBase 的聚合性质:

Public Class WebOrder
    Inherits OrderBase        

    Public Overrides Property OrderItem as WebOrderItem 
    End Property
End Class

Public Class WebOrderItem
    Inherits OrderItemBase
End Class

WebOrder 类中的 Overriden 属性将导致错误,指出返回类型与 OrderBase 中定义的不同……但是,返回类型是 OrderBase 中定义的类型的子类。为什么VB不允许这样做?

4

3 回答 3

7

你不能这样做 - 它正在改变基础上定义的签名。要执行您想要执行的操作,您需要使用泛型:

Public Class OrderBase(Of T As IOrderItem)
    Public ReadOnly Property OrderItems As IList(Of T)
End Class

我的 Visual Basic 生锈了,所以希望那是准确的......

于 2010-05-07T18:03:05.597 回答
4

您无法在覆盖类时更改其签名。但是,您可以返回派生类型:

Public Overrides Property OrderItem() as OrderItemBase
    Get
        Return New WebOrderItem()
    End Get
End Property

Public Sub Whatever()
    Dim item As WebOrderItem = DirectCast(OrderItem, WebOrderItem)
End Sub

或者,如果您想更严格地执行类型,请使用具有泛型类型约束的泛型,如下所示:

Public MustInherit Class OrderBase(Of T As OrderItemBase)
    Public MustOverride ReadOnly Property OrderItem() As T
End Class

Public Class OrderItemBase
End Class

Public Class WebOrder(Of T As WebOrderItem)
    Inherits OrderBase(Of T)

    Public Overrides ReadOnly Property OrderItem() As T
        Get
            Return New WebOrderItem()
        End Get
    End Property
End Class

Public Class WebOrderItem
    Inherits OrderItemBase
End Class

或者,如果您不希望 WebOrder 也成为泛型类,请执行此操作:

Public Class WebOrder
    Inherits OrderBase(Of WebOrderItem)

    Public Overrides ReadOnly Property OrderItem() As WebOrderItem
        Get
            Return New WebOrderItem()
        End Get
    End Property
End Class
于 2010-05-07T18:19:39.047 回答
4

一种方法是拥有一个受保护的可覆盖方法,然后拥有一个调用可覆盖方法的公共不可覆盖方法。每当派生类中函数的返回值发生变化时,对可覆盖方法进行不可覆盖的覆盖,调用一个新的可覆盖方法,该方法返回更精确的类型,并使用使用新的覆盖。如果 vb.net 允许一个类同时覆盖和隐藏同一个成员,事情会干净得多,但没有办法做到这一点。

Public Class CarFactory
  Protected Overridable Function DerivedMakeCar() as Car
    ' make a car
  End Function

  Public Function MakeCar() as Car
    Return DerivedMakeCar()
  End Function

End Class

Public Class FordFactory
  Inherits CarFactory

  Protected Overrides Function DerivedMakeCar() As Car
    Return DerivedMakeFord()
  End Function

  Protected Overridable Function DerivedMakeFord() As Ford
    ' Make a Ford
  End Function

  Public Shadows Function MakeCar() As Ford
    Return DerivedMakeFord()
  End Function

End Class

在某些情况下,更简单的替代方法可能是拥有一个公共的可重写 MakeCar() 函数,该函数始终返回一个类型为 的对象Car,但让 FordFactory 还包含一个返回 Ford 的 MakeFord() 函数。

被覆盖的 MakeCar() 函数将NotOverridable简单地调用 MakeFord。在某些方面,后一种方法可能更简洁,但如果有一个通用的命名约定(例如,工厂有一个 MakeProduct 方法,它返回最派生的类型),则使用 Shadows 可能很有用。

于 2010-10-27T23:07:23.253 回答