我的例子是在 vb.net 中(我正在学习 C#,但还没有“那里” - 差异不是那么大以至于这没有意义,虽然......),但要领是失败的普遍的。您有一个基类 Animal,以及一些从动物派生的类。在您的基类上定义 .Move 方法。然后创建派生类,继承基类的方法和公共接口。定义 AnimalType 属性以区分动物的类型。对于这个非常简单的示例,我使用了 Enum。实际上,这可能是一个 Enum,也可能是一个数据库 PK 或其他唯一标识符。请注意,在实践中,我可能不会让 superType Animal 成为与派生类相同的枚举的成员。例如,在数据库中,我可能会将派生对象设为与“父”动物记录相关的“子”记录):
Public Enum AnimalTypes
Animal = 1
Pig = 2
Human = 3
End Enum
Public Class AnimalBase
Public Overridable ReadOnly Property AnimalType() As AnimalTypes
Get
Return AnimalTypes.Animal
End Get
End Property
Public Sub Move(ByVal X As Integer, ByVal Y As Integer)
' . . . You movement code
End Sub
End Class
现在你的派生类:
Public Class Pig
Inherits AnimalBase
Public Overrides ReadOnly Property AnimalType() As AnimalTypes
Get
Return AnimalTypes.Pig
End Get
End Property
'A property spcific to the pig class:
Public ReadOnly Property PigOnEquality() As String
Get
Return "Some pigs are more equal!"
End Get
End Property
End Class
Public Class Human
Inherits AnimalBase
Public Overrides ReadOnly Property AnimalType() As AnimalTypes
Get
Return AnimalTypes.Human
End Get
End Property
'A property specific to the Human class:
Public ReadOnly Property Shotgun() As String
Get
Return "Boom!"
End Get
End Property
End Class
现在,一个 AnimalFactory 类,它创建了 animal 的实例和派生自类型 animal 的类,如(再一次......类型 animal):
Public Class AnimalFactory
Public Shared Function NewAnimal(ByVal AnimalType As AnimalTypes) As AnimalBase
Select Case AnimalType
Case AnimalTypes.Animal
Return New AnimalBase
Case AnimalTypes.Pig
Return New Pig
Case AnimalTypes.Human
Return New Human
Case Else
Return New AnimalBase
End Select
End Function
End Class
这里的诀窍是,由 AnimalFacorty 返回的派生类是动物类型,但实现了它们真实类型的所有属性,如果需要,可以将其强制转换为它们的真实类型。现在,你的表格。如果您只访问在基类上定义的常用方法,您的表单也不必关心返回的动物类型。如果您需要访问特定于派生类的方法,则需要执行强制转换操作(在 C# 中应该与在 VB.net 中相同(或非常相似)。
我以这种形式抛出了一些非常愚蠢的例子。也有可能避免 Select Case 的方法(我相信你会知道作为 Switch 语句),但我不知道你在用你的代码做什么,所以这只是一个 acedmic excercise 。 . .
Public Class AnimalFarm ' My hilarious name for the FORM
'Member variable for the currently selected instance of AnimalBase
Private SelectedAnimal As AnimalBase
Private Sub AnimalFarm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'Using the enum to populate the comboBox:
With Me.ComboBox1.Items
.Add(AnimalTypes.Animal)
.Add(AnimalTypes.Pig)
.Add(AnimalTypes.Human)
End With
End Sub
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim AnimalType As AnimalTypes = Me.ComboBox1.SelectedItem
Me.OnNewAnimalSelected(AnimalType)
End Sub
Private Sub OnNewAnimalSelected(ByVal AnimalType As AnimalTypes)
SelectedAnimal = AnimalFactory.NewAnimal(AnimalType)
'The form doesn't case what type of animal is being instantiated, so long
'as the methods required are defined on the base class:
MsgBox(SelectedAnimal.AnimalType.ToString)
'Move the animal a bit, just for kicks:
SelectedAnimal.Move(NewX, NewY)
' . . . But if you NEED the specific TYPE of animal:
Select Case SelectedAnimal.AnimalType
Case AnimalTypes.Human
Dim NewHuman As Human = CType(SelectedAnimal, Human)
MsgBox(NewHuman.Shotgun)
Case AnimalTypes.Pig
Dim Piggy As Pig = CType(SelectedAnimal, Pig)
MsgBox(Piggy.PigOnEquality)
Case Else
MsgBox("This Animal has nothing to say . . .")
End Select
End Sub
Private Sub OnMoveAnimal(ByVal X As Integer, ByVal Y As Integer)
SelectedAnimal.Move(X, Y)
End Sub
End Class