2013-07-02 3 views
0

Я хотел бы объявить переменные уровня класса для группы дочерних классов, подобных этому в python: Static class variables in Python. Я узнал, что атрибут shared - это, вероятно, то, что я хочу использовать, но я не совсем уверен, где его использовать.Объявить переменные уровня класса в дочернем классе

Вот моя ситуация: Я делаю кучу разных типов символов для игры (100+). Все типы символов имеют одинаковый набор свойств, поэтому я создал базовый класс, который включает все свойства и необходимые внутренние переменные. Каждый тип символа имеет набор неизменяемых свойств, которые абсолютно одинаковы для каждого экземпляра заданного типа символа, но различаются между типами символов. Я хотел бы содержать свойства неизменяемого символьного типа как «переменные» класса в дочерних классах (один дочерний класс для типа символа), как в ответе на приведенный выше пример python.

Ключ в том, что я хотел бы ссылаться на некоторые свойства БЕЗ создания экземпляра подкласса.

Моя проблема заключается в том, что я не могу понять, что нужно использовать, чтобы правильно это сделать или как мой код должен быть организован, чтобы это произошло. Я попробовал поделиться свойствами, которые в конечном итоге позволили мне получить свойства из дочернего класса, а не только экземпляр дочернего элемента, но затем он не вернет свойство, которое я назначил в дочернем классе, используя Shared или Shared Shadows. Я хотел бы сохранить свойства в базовом классе, так что мне не нужно копировать и вставлять те же свойства для каждого дочернего класса.

Вот некоторые образцы моего кода:

Public MustInherit Class Char 

    'IMMUTABLE INFORMATION 
    ' CharType Traits 
    Shared _ID As Integer 
    Shared _Species As String 

    Public Shared ReadOnly Property Species As String 
     Get 
      Return _Species 
     End Get 
    End Property 
End Class 

Public Class CharCat 
    Inherits Char 

    Shared Shadows _Species = "Cat" 
End Class 

Цель состоит в том, чтобы иметь возможность ввести CharCat.Species и он вернется "Cat". Я знаю, что этот пример избыточен с именем класса, но для других свойств это не так.

+2

Я бы не назвал класс 'Char', поскольку это зарезервированное слово – Michael

+0

« Я хотел бы сохранить свойства в базовом классе, так что мне не нужно копировать и вставлять те же свойства для каждого дочернего класса. " Вы должны копировать и вставлять объявление переменной в каждый класс. Кроме того, если свойство ReadOnly, ему действительно нужна личная переменная? Почему бы просто не вернуть соответствующую строку для каждого подтипа? –

+0

@Idle_Mind, я бы хотел, чтобы код был короче и легче читать. Если возможно, было бы неплохо, чтобы каждый дочерний класс имел одну строку на набор свойств/переменных. Решение NoAlias ​​работает ниже, и если для каждого типа символа требуется 5 строк на каждое свойство, для каждого типа символа должно быть 5 строк на одно свойство, но если я могу его конденсировать, я бы с удовольствием. – Paul

ответ

1

Использование ответа NoAlias ​​как платы весны в сотрудничестве с большим количеством исследований и вопросов SO, я нашел полный ответ. Базовый класс НЕ нужен Overridable, учитывая, что, поскольку дочерний класс использует Shared, он НЕ МОЖЕТ иметь свойство Overrides. Overloads, как сообщается, ничего не делает для свойства в соответствии с Hans Passant, поэтому нам это тоже не нужно.

Теперь код работает с этими двумя изменениями, но есть предупреждающий флаг, в котором говорится, что свойство должно быть объявлено как «перегрузки», которое на самом деле не является правильным решением. Чтобы правильно избавиться от предупреждения, необходимо объявить Shadows. Код работал без объявления теней, потому что Shadowing is the default behavior for a child property, но для того, чтобы избавиться от предупреждающих бросков VB, вам нужно явно объявить его.

код заканчивает тем, как это:

Public MustInherit Class [Char] 

    Private _ID As Integer 
    Private _Species As String 

    Public ReadOnly Property Species As String 
     Get 
      Return _Species 
     End Get 
    End Property 

End Class 

Public Class CharCat 
    Inherits Char 

    Public Shared Shadows ReadOnly Property Species As String 
     Get 
      Return "Cat" 
     End Get 
    End Property 

End Class 

Private Sub Form1_Load(ByVal sender As System.Object, _ 
    ByVal e As System.EventArgs) Handles MyBase.Load 

    MsgBox(CharCat.Species) 

End Sub 

Важно отметить, что теперь мы имеем дело с Shadows поведения. Если дочерний класс вызывается через родительский класс, вы получите поведение родительского класса для свойства. Для меня, поскольку я не мог использовать Overrides, потому что я использую Shared, я решил, что лучший способ избежать поведения родительского класса - это просто получить удовольствие от свойства родительского класса, так как он не имел никакой важной информации. Вы можете попробовать быть супер осторожным, чтобы не вызвать ребенка через родителя в вашем коде, чтобы избежать поведения родителя.

3

Вы можете сделать свойство свойства BaseClass доступным для достижения того, что вы ищете.

Public MustInherit Class [Char] 

    Private _ID As Integer 
    Private _Species As String 

    Public Overridable ReadOnly Property Species As String 
     Get 
      Return _Species 
     End Get 
    End Property 

End Class 

Public Class CharCat 
    Inherits Char 

    Public OverLoads Shared ReadOnly Property Species As String 
     Get 
      Return "Cat" 
     End Get 
    End Property 

End Class 

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 

    MsgBox(CharCat.Species) 

End Sub 
+0

Это работает, но он заставит мой код SUPER LONG перечислить 10 геттеров для каждого свойства из 100+ типов символов. Вы знаете, есть ли способ сделать это более сжато? – Paul

+0

Также вы можете объяснить, почему требуется «перегрузки»? Похоже, что он не соответствует стандартным правилам перегруженного метода с уникальными параметрами, так почему он работает и зачем он нужен? – Paul

+0

Вам придется измельчить всех этих геттеров. Использование класса MustOverride/свойств в CharClass может облегчить вам работу, поскольку, когда вы наследуете от одного VS, вы автоматически генерируете для вас свойство. Перегрузки должны были быть переопределениями, и я обновил свой ответ. – N0Alias

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