Inheritance and overloading

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))

Is this possibly a capitalization error?

No, Xojo code is not case sensitive.

It sounds like the definition of TempSensors.name is not correct.

Haha, you learn something new everyday!

You need to use the actual name of the method.

TempSensors needs a “name” property.

1 Like

Closer. It does not error now but the first column of the listbox is blank. I added “name as string” to the properties of the super class TempSensors.

Only methods can be overridden by a subclass.

Is the name of the method you’re trying to override “Name” or is it “Sensor”?

For those that are interested I’m following the example: Object-Oriented Programming Concepts on YouTube.

Initialize the name property in the constructor of each subclass.

1 Like

“Sensor”

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.

1 Like

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.

OR

I need constructors as you mentioned.

Initialize SensorName in each subclass’ constructor, not in the Sensor method.

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.

1 Like

A construct did it. Thanks for getting me there.

1 Like

So if I changed

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)