VB.NET类的子类,包含子类项的列表集合

时间:2016-10-26 14:42:58

标签: vb.net list subclass generic-list

考虑一个名为Fruit的类和一个名为FruitStand的类,它包含一个通用的Fruit列表,并公开一个属性(Contents)来获取Fruit的类,以便在类中迭代Fruit。

现在我想创建一个Apple类,它是Fruit的子类,我想要一个名为AppleCart的类,它是FruitStand的子类。 AppleCart中通用List的内容只包含Apple类的内容。我想要的是能够让AppleCart的消费者不必将内容属性返回的元素从Fruit转移到Apple。

我希望这是一件简单的事情,我只是心理障碍。

3 个答案:

答案 0 :(得分:2)

您可以在FruitStand类上使用泛型约束,这会强制派生类在其声明中指定派生自Fruit的类

Sub Main()
    Dim ac As New AppleCart({New Apple(), New Apple()})
    For Each a In ac.Fruits
        a.Rot() ' prints "The apple is rotten!"
    Next
    Console.Read()
End Sub

Public Class Fruit
    Public Overridable Sub Rot()
        Console.WriteLine("The fruit is rotten!")
    End Sub
End Class

Public Class Apple
    Inherits Fruit
    Public Overrides Sub Rot()
        Console.WriteLine("The apple is rotten!")
    End Sub
End Class

Public Class FruitStand(Of T As Fruit)
    Private _fruits As List(Of T)
    Public ReadOnly Property Fruits As IEnumerable(Of T)
        Get
            Return _fruits
        End Get
    End Property
    Public Sub New(fruits As IEnumerable(Of T))
        _fruits = fruits.ToList()
    End Sub
End Class

Public Class AppleCart
    Inherits FruitStand(Of Apple)
    Public Sub New(fruits As IEnumerable(Of Apple))
        MyBase.New(fruits)
    End Sub
End Class

答案 1 :(得分:2)

您可以使用泛型。

Sub Main()

    Dim cart As New AppleCart

    cart.Fruits.Add(New Apple)

End Sub

Class FruitStand(Of T As Fruit)

    Public Property Fruits As List(Of T)

End Class

Class Fruit

End Class

Class AppleCart
    Inherits FruitStand(Of Apple)

End Class

Class Apple
    Inherits Fruit

End Class

答案 2 :(得分:1)

我看到了3个选项:你可以像FruitStand这样通用:

Class FruitStand(Of TFruit As Fruit)
  Public ReadOnly Property Contents As List(Of TFruit)
End Class

NotInheritable Class AppleCart
  Inherits FruitStand(Of Apple)
End Class

或者你切断FruitStandAppleCart之间的关系,而是从同一个新提取的基类派生它们(我认为这是最好的选择):

MustInherit Class FruitStandBase(Of TFruit As Fruit)
  Public ReadOnly Property Contents As List(Of TFruit)
End Class

NotInheritable Class FruitStand
  Inherits FruitStandBase(Of Fruit)
End Class

NotInheritable Class AppleCart
  Inherits FruitStandBase(Of Apple)
End Class

在这两种情况下,我都密封了派生的AppleCart,因为从中派生的类型不会覆盖TFruit的类型。在层次结构中的那一点,Contents的类型将被关闭。

最后,您可以使用阴影来更改更多派生类型中Contents的含义。问题是:您必须为基本类型的Contents属性使用协变集合(这意味着使用只读接口,例如IReadOnlyList(Of Fruit)或数组 - 无论哪种方式,您都失去了添加或删除元素):

Class FruitStand

  Public ReadOnly Property Contents As IReadOnlyList(Of Fruit)

  Public Sub New()
    Me.New(New List(Of Fruit))
  End Sub

  Protected Sub New(contents As IReadOnlyList(Of Fruit))
    Me.Contents = contents
  End Sub

End Class

Class AppleCart
  Inherits FruitStand

  Public Shadows ReadOnly Property Contents As IReadOnlyList(Of Apple)
    Get
      Return CType(MyBase.Contents, IReadOnlyList(Of Apple))
    End Get
  End Property

  Public Sub New()
    MyBase.New(New List(Of Apple))
  End Sub

End Class