2016-10-26 4 views
-1

Рассмотрите класс с именем Fruit и класс с именем FruitStand, который содержит общий список фруктов и предоставляет свойство (Содержание), чтобы получить Список фруктов для купирования итерации Плод в классе.Подкласс класса VB.NET, содержащий набор списков подклассов

Теперь я хочу создать класс Apple, который является подклассом Fruit, и мне нужен класс под названием AppleCart, который является подклассом FruitStand. Содержимое общего списка в AppleCart будет только когда-либо включать в себя класс Apple. Я хочу, чтобы потребитель AppleCart не мог отображать элементы, возвращенные свойством Contents, Apple от Fruit.

Я надеюсь, что это что-то простое, что у меня просто есть ментальный блок.

+0

Если AppleCart может содержать только Яблоки, зачем кому-то его бросать? – Plutonix

+0

Вместо того, чтобы AppleCart унаследовал от FruitStand, возможно, интерфейс (например, 'IFruitVendor (of T)') будет делать то, что вы хотите. – Plutonix

+0

Becuase SuperClass (FruitStand) возвращает список фруктов, а не список Apple. Таким образом, потребитель должен был бы бросить Фрут, возвращенный из перечислителя, в Apple, чтобы получить доступ к свойствам, характерным для Apple. Корзина Apple содержит только Яблоки, потому что она гарантирует, что в список будут добавлены только Яблоки. – rcp

ответ

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 
+0

Я знал, что у меня что-то очень простое. Благодаря! – rcp

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

Я вижу 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 
+0

Все три подхода имеют свои достоинства. Для моих целей простейший подход (создание общего набора FruitStand) был достаточным, как указано в ответе thelot. – rcp

 Смежные вопросы

  • Нет связанных вопросов^_^