【问题标题】:Declare Class Level Variables in Child Class在子类中声明类级变量
【发布时间】:2013-07-08 23:32:39
【问题描述】:

我想在 python 中为一堆与此类似的子类声明类级变量:Static class variables in Python。我了解到shared 属性可能是我想要使用的,但我不太确定在哪里使用它。

这是我的情况:我正在为一个游戏(100 多个)制作一堆不同的角色类型。所有字符类型都具有相同的属性集,因此我创建了一个包含所有属性和所需内部变量的基类。每个字符类型都有一组不可变的属性,这些属性对于给定字符类型的每个实例完全相同,但在字符类型之间有所不同。我想在子类(每个字符类型一个子类)中包含不可变字符类型属性作为类“变量”,就像上面对 python 示例的答案一样。

关键是我想引用一些属性而不必创建子类的实例。

我的问题是我无法弄清楚需要共享什么才能正确执行此操作,或者我的代码需要如何组织才能实现此目的。我尝试共享属性,这最终允许我从子类获取属性,而不仅仅是子类的实例,但它不会返回我使用SharedShared 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"。我知道这个例子对于类名是多余的,但对于其他属性却不是。

【问题讨论】:

  • 我不会调用类Char,因为它是保留字
  • “我想将属性保留在基类中,这样我就不必为每个子类复制和粘贴相同的属性。”无论如何,您必须将变量声明复制并粘贴到每个类中。另外,如果属性是只读的,那么它真的需要它后面的私有变量吗?为什么不只为每个子类型返回适当的字符串?
  • @Idle_Mind,我更希望代码更短且更易于阅读。如果可能的话,最好让每个子类的每个属性/变量集都有一行。 NoAlias 的解决方案在下面有效,如果每个字符类型每个属性需要 5 行,那么每个字符类型每个属性需要 5 行是我必须使用的,但如果我可以浓缩它,我很乐意。

标签: vb.net class shared


【解决方案1】:

您可以将 BaseClass Species 属性设为 Overridable 以实现您想要的。

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

【讨论】:

  • 这行得通,但它会让我的代码超长,必须为 100 多个字符类型的每个属性列出 10 个吸气剂。你知道是否有更简洁的方法吗?
  • 另外,你能解释一下为什么需要“过载”吗?它似乎没有遵循具有唯一参数的标准重载方法约定,那么为什么它会起作用,为什么需要它?
  • 你必须磨掉所有这些吸气剂。在 CharClass 中使用 MustOverride Class / Properties 可能会让您更容易,因为当您从一个 VS 继承时,会自动为您生成属性。重载应该是覆盖,我已经更新了我的答案。
  • 您不能对同一个属性使用“覆盖”和“共享”...“重载”有效并且不会引发警告标志,但它对我来说没有意义...
【解决方案2】:

使用 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,所以我决定避免父类行为的最好方法是直接使用父类属性,因为它没有任何重要的反正信息。您可以尝试非常小心,不要在代码中通过父级调用子级,以避免父级行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多