Inheritance Question

Z

z71mdridin

I have three classes:

Public MustInherit Class Animal
Public MustOverride Function speak() As String
End Class
Public Class dog
Inherits Animal
Public Overrides Function speak() As String
Return "Bark"
End Function
End Class
Public Class cat
Inherits Animal
Public Overrides Function speak() As String
Return "Meow"
End Function
End Class

I want to create a front-end and allow the user to choose dog or cat
from a drop down and then call the appropriate method. Is this
possible to do without using a case statement? I would like to create
an instance of animal and then cast it to whatever the user has
chosen. Is this possible in vb.net?

Dim testanimal As Animal
CType(testanimal, Combobox1.SelectedValue)
testanimal.speak()
 
T

Tom Shelton

I have three classes:

Public MustInherit Class Animal
Public MustOverride Function speak() As String
End Class
Public Class dog
Inherits Animal
Public Overrides Function speak() As String
Return "Bark"
End Function
End Class
Public Class cat
Inherits Animal
Public Overrides Function speak() As String
Return "Meow"
End Function
End Class

I want to create a front-end and allow the user to choose dog or cat
from a drop down and then call the appropriate method. Is this
possible to do without using a case statement? I would like to create
an instance of animal and then cast it to whatever the user has

You can't create an instance of animal, it is abstract...
chosen. Is this possible in vb.net?

Dim testanimal As Animal
CType(testanimal, Combobox1.SelectedValue)
testanimal.speak()

ComboBox1.Items.Add (New Dog())
ComboBox1.ITems.Add (New Cat())

....

Dim TestAnimal As Animal = CType (ComboBox1.SelectedValue, Animal)
TestAnimal.Speak()
 
A

Armin Zingler

z71mdridin said:
I want to create a front-end and allow the user to choose dog or cat
from a drop down and then call the appropriate method. Is this
possible to do without using a case statement? I would like to
create an instance of animal and then cast it to whatever the user
has chosen. Is this possible in vb.net?

Dim testanimal As Animal
CType(testanimal, Combobox1.SelectedValue)
testanimal.speak()


In order to create an object, the New keyword should be used whenever
possible. (IMO) Reflection should only be applied if the type can not be
determined. In your case, it is possible to infer the type from the
selection made. Therefore I suggest using a Select Case statement.


Though, to demonstrate the reflected way:

Class ComboItem
Public ReadOnly Type As Type
Sub New(ByVal Type As Type)
Me.Type = Type
End Sub
Public Overrides Function ToString() As String
Return Type.Name
End Function
End Class

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

With Me.ComboBox1.Items
.Add(New ComboItem(GetType(dog)))
.Add(New ComboItem(GetType(cat)))
End With

End Sub

Private Sub Button1_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click

Dim Item = DirectCast(Me.ComboBox1.SelectedItem, ComboItem)
Dim Animal = DirectCast(Activator.CreateInstance(Item.Type),
Animal)

MsgBox(Animal.speak())

End Sub


Armin
 
J

jonathan.whitehurst

What I would really want to do is store the animal types in a database
and then at run-time display those types in a list box and allow the
user to choose. I would like to be able to add new animal
types( chicken, cow, etc) and only add the new class to the class
library and then add a new record to the database without having to
make any modifications to the front end code. I am getting the
feeling this is not possible though, as I will always need to
ComboBox.Add(New ComboItem(GetType("cow"))) for each new animal
subclass I add. Am I correct that this is not possible? Thanks for
the help!
 
A

Armin Zingler

What I would really want to do is store the animal types in a
database and then at run-time display those types in a list box and
allow the user to choose. I would like to be able to add new animal
types( chicken, cow, etc) and only add the new class to the class
library and then add a new record to the database without having to
make any modifications to the front end code. I am getting the
feeling this is not possible though, as I will always need to
ComboBox.Add(New ComboItem(GetType("cow"))) for each new animal
subclass I add. Am I correct that this is not possible? Thanks for
the help!

No, it is possible. Before, you've described a different situation.
That's why I manually used "..GetType.." for each class available in the
example.

You can load the type names from the database and add them to a Combobox
in a loop without knowing how many there will be. You will have to plan
which information about the type you want to store in the database. A
type name can contain a namespace, and to be exact, the information
about the assembly containing the class could also be stored. I assume
it's the same assembly.

For example, if you loaded the type names into an array called
'TypeNames':

With Me.ComboBox1.Items
For Each TypeName As String In TypeNames
.Add(New ComboItem( _
Type.GetType("WindowsApplication1.Form1+" & TypeName) _
))
Next
End With



However, as you're using Reflection anyway, you might retrieve the
available types from the executing assembly. This way you could get rid
of the redundant storage in the database. Have a look at the method
Assembly.GetTypes. In addition, you can add your own attributes
to the class if something from the database is missing.


Armin
 
G

Guest

I want to create a front-end and allow the user to choose dog or cat
from a drop down and then call the appropriate method. Is this
possible to do without using a case statement? I would like to create
an instance of animal and then cast it to whatever the user has
chosen. Is this possible in vb.net?

Yes this is possible - you can use reflection to iterate through all types
in your project. If the type inherits from Animal (your base type), you add
it to the list.

It's actually quite easy to do:

For Each AssemblyType As Type In
System.Reflection.Assembly.GetExecutingAssembly.GetTypes
'Check if base type inherits from Animal
If AssemblyType.BaseType Is GetType(Animal) Then
'Load into combo Box here
End If
Next


If you have multiple level inheritance, i.e. Animal -> Mammal -> Primates
-> Monkey, you'll need to write a recursive search to check the entire
inheritance hierachy.
 
B

Bill McCarthy

Spam Catcher said:
Yes this is possible - you can use reflection to iterate through all types
in your project. If the type inherits from Animal (your base type), you
add
it to the list.

It's actually quite easy to do:

For Each AssemblyType As Type In
System.Reflection.Assembly.GetExecutingAssembly.GetTypes
'Check if base type inherits from Animal
If AssemblyType.BaseType Is GetType(Animal) Then
'Load into combo Box here
End If
Next


If you have multiple level inheritance, i.e. Animal -> Mammal -> Primates
-> Monkey, you'll need to write a recursive search to check the entire
inheritance hierachy.


It might be simpler to use Type.IsSubClassOf instead ;)
 
Z

z71mdridin

Thanks for all the help so far. I am still getting an error though. I
created a ComboItem class so that I could pass in name and value pair
to the combox. However when retrieving from the combobox I get An
unhandled exception of type 'System.InvalidCastException' occurred.
Anyone have any ideas on what I am doing wrong?

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
For Each AssemblyType As Type In
System.Reflection.Assembly.GetExecutingAssembly.GetTypes()
'Check if base type inherits from Animal
If AssemblyType.BaseType Is GetType(Animal) Then
'Load into combo Box here
ComboBox1.Items.Add(New ComboItem(AssemblyType.Name,
AssemblyType))
End If
Next
End Sub

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
ComboBox1.SelectedIndexChanged
' Dim Item = CType(Me.ComboBox1.SelectedItem, ComboItem)
'Dim Animal = DirectCast(Activator.CreateInstance(Item.Type),
Animal)
' MsgBox(Animal.speak())
Dim ComboItem = CType(ComboBox1.SelectedItem,
ComboItem).ItemData
Dim TestAnimal = CType(ComboItem, Animal)
TestAnimal.speak()
End Sub

Public Class ComboItem
' Declare the variable the property uses.
Private strItemData As Type
Private strItem As String
Public Property ItemData() As Type
Get
Return strItemData
End Get
Set(ByVal ItemData As Type)
strItemData = ItemData
End Set
End Property

Public Property Item() As String
Get
Return strItem
End Get
Set(ByVal Item As String)
strItem = Item
End Set
End Property
Public Overrides Function ToString() As String
Return strItem
End Function
Public Sub New()
End Sub
Public Sub New(ByVal Item As String, ByVal ItemData As Type)
strItem = Item
strItemData = ItemData
End Sub
End Class
 
J

jonathan.whitehurst

Nevermind, I figured it out. I was using an old ComboItem class.
Thanks for all your help!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top