I’m try to better understand how to use Inheritance and overloading so I created a number of sensor classes that are all related to one super class. In each of the sensor classes is one method with the same name that calculates its temperature value. In a push button I created an array of these sensors so the code looks like this:
Var Sensors() As TempSensors
Sensors.Append(New UpstairsTemp)
Sensors.Append(New KitchenTemp)
Sensors.Append(New CeilingTemp)
Sensors.Append(New FloorIntakeTemp)
Sensors.Append(New StorageAreaTemp)
Sensors.Append(New BedroomTemp)
ListBox1.RemoveAllRows
For Each S As TempSensors In Sensors
ListBox1.AddRow(Str((???))) // first column
ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Str(S.Sensor) // second column
Next
Is there a reference or way to populate the first column (???) of the listbox or later a dictionary with the name of the sensor?
The common superclass (TempSensors) must also have the method. The subclasses then inherit this method and may override it with their own implementation.
For Each S As TempSensors In Sensors
ListBox1.AddRow(S.Name)
This invokes the Name method on the TempSensors reference; if the reference is actually a subclass of TempSensors then the Name method on the subclass is invoked.
Yes, that is what I thought but it’s not working yet. As you say my common super class has an empty method with the same name as the TempSensors sub classes with the override code but,
ListBox1.AddRow(S.name) yields an error:
Type “TempSensors” has no member named “name”
My subclassed method called Sensor() has this code:
Return ConvertSensorValLowTemp(ReadSensor(“BK7”,4))
To be more complete, classes don’t have names. You can get the class type through introspection, but that’s a lot of needless work. Add a string property to the superclass and set it to whatever you want in each of the subclasses.
Okay, I now have a string property in the super class called SensorName and in the subclass method Sensor :
SensorName = “Bedroom Temp” //Different for each subclass
Return ConvertSensorValLowTemp(ReadSensor(“BK7”,7))
The buttons action event now his this:
Var Sensors() As TempSensors
Sensors.Append(New UpstairsTemp)
Sensors.Append(New KitchenTemp)
Sensors.Append(New CeilingTemp)
Sensors.Append(New FloorIntakeTemp)
Sensors.Append(New StorageAreaTemp)
Sensors.Append(New BedroomTemp)
ListBox1.RemoveAllRows
For Each S As TempSensors In Sensors // number of controls in window
ListBox1.AddRow(S.SensorName) // first column
ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Str(S.Sensor) // second column
Next
Nothing shows in column one so feel I’m not setting the name (S.SensorName) correctly.
For clarification, the problem is that you’re using S.SensorName in your code before you’re running the S.Sensor method that initializes S.SensorName.
Although, I would like to mention that using constructors is a generally “better” way to do this. Having an arbitrary method initialize a subclass’s field can make it hard to follow your code later.
ListBox1.RemoveAllRows
For Each S As TempSensors In Sensors // number of controls in window
ListBox1.AddRow(S.SensorName) // first column
ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Str(S.Sensor) // second column
Next
to this:
ListBox1.RemoveAllRows
For Each S As TempSensors In Sensors // number of controls in window
ListBox1.CellValueAt(Listbox1.LastAddedRowIndex, 1) = Str(S.Sensor) // second column
ListBox1.AddRow(S.SensorName) // first column
Next
it would work or would it need to be initialized in another method first?
A new problem arises: since you haven’t run ListBox1.AddRow before using ListBox1.LastAddedRowIndex, you’ll be adding the column to the wrong row.
(but yes, if this problem hadn’t arisen, you would be absolutely correct)