考虑一个名为Fruit的类和一个名为FruitStand的类,它包含一个通用的Fruit列表,并公开一个属性(Contents)来获取Fruit的类,以便在类中迭代Fruit。
现在我想创建一个Apple类,它是Fruit的子类,我想要一个名为AppleCart的类,它是FruitStand的子类。 AppleCart中通用List的内容只包含Apple类的内容。我想要的是能够让AppleCart的消费者不必将内容属性返回的元素从Fruit转移到Apple。
我希望这是一件简单的事情,我只是心理障碍。
答案 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
或者你切断FruitStand
和AppleCart
之间的关系,而是从同一个新提取的基类派生它们(我认为这是最好的选择):
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