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

1 つの方法は、保護されたオーバーライド可能なメソッドを用意し、オーバーライド可能なメソッドを呼び出すオーバーライド不可能なパブリック メソッドを用意することです。派生クラスの関数の戻り値が変更される必要があるときはいつでも、オーバーライド可能なメソッドのオーバーライド不可能なオーバーライドで、より洗練された型を返す新しいオーバーライド可能なメソッドを呼び出し、パブリック関数の以前のバージョンを、新しいオーバーライド。vb.net で 1 つのクラスが同じメンバーのオーバーライドとシャドウの両方を許可した場合、事態はよりクリーンになりますが、それを行う方法はありません。

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

場合によっては、より簡単な代替手段として、常に type のオブジェクトを返すオーバーライド可能な public の MakeCar() 関数を用意しCar、FordFactory に Ford を返す MakeFord() 関数を含めることもできます。

オーバーライドされた MakeCar() 関数はNotOverridable、単純に MakeFord を呼び出します。いくつかの点で、後者のアプローチの方がクリーンですが、共通の命名規則がある場合 (たとえば、ファクトリには最も派生した型を返す MakeProduct メソッドがある場合)、Shadow を使用すると便利な場合があります。

于 2010-10-27T23:07:23.253 に答える
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 に答える