Sub classing and Inheritance

I think I understand the global storage such as in a module and guess a dictionary in a module covers the individual sensor values. I’m not sure what memory each temp sensor object means yet. I now believe you are storing the sensor object, not just the values. I’ll have to figure out how to do that.

If I have an push button event handler that has this code:

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)

Sensors.Append(New BoilerTemp)
Sensors.Append(New LoopPumpTemp)
Sensors.Append(New DHWTankTemp)
Sensors.Append(New OutsideTemp)
Sensors.Append(New CloudSensor)
Sensors.Append(New DuskSensor)

Sensors.Append(New CalSensor14)
Sensors.Append(New CalSensor15)

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

This takes advantage of a TempSensors class with all of the methods and properties which then is subclassed to Sensors… This all works.

In a modules properties I placed Sensors() as TempSensors thinking I would have a persistent reference to my sensor values. A push bottom with MessageBox str(Sensors(1).sensor_Avg), sensor_Avg being a property of TempSensors yields an exception after I run the sequence one. I thought I would have an persistent array of sensor values. Where am I going wrong with this thought process?

This creates a local variable that will be used instead of the global one. This variable and the objects it contains will go out of scope and be destroyed when the event ends. Try commenting this line out.

what is the difference between this classes? i wonder why you use so many classes if they all read a temperature.

you can also store a object in the RowTag at your list but if the values changed the cells need a update.

If I have an push button event handler that has this code:

seems you fetch the values and update this list.

if you put this global " Sensors() as TempSensors"
then you can init it once in your open window event.

if the sensors need an update use a timer event and make a .Update Method in Sensor class that it read the values again. after update refresh the list row as example.

Check out the book “Head first design patterns”: https://www.amazon.de/First-Design-Patterns-Brain-Friendly/dp/0596007124/ . The book is old but the principles are timeless. The code is in Java. I have a very old Xojo implementation at https://www.mothsoftware.com/downloads/headfirstdesignpatterns1.1.zip .

Working only with inheritance makes the design somewhat brittle. What is the difference between your sensors? How do they behave? That’s what makes your classes and not the location.

1 Like

https://en.wikipedia.org/wiki/Software_design_pattern /

BR Rainer

It would be nice to see these design patterns written in XOJO. I down loaded the PDF but I’m sure I’m not quite ready for it. My skills are way too primitive.

This was not the first time you needed to bring this to my attention. I get it but missed removing it from the class method this time when I move it to a module, thanks. So far your suggestion of a constructor and assigning a name to each sensor has worked great since I can use it as a key in a dictionary and store it with a Json file if I wish. I found that Sensors() As TempSensors doesn’t work as well in a module for me since the array grows on each iteration. I could reset it but what would be the advantage over a dictionary. From a dictionary, I can call it by name anywhere. It does feel a little strange to create that many classes for the senors but I do have four different flavors of those sensors which are addressed in the super, so it works fine. I was thinking I could use Sensors() As TempSensors in a module for a better averaging method since that array appends being persistent.

Thanks, MarkusR for your thoughts on this. You mentioned it would be practical to use a timer and bulk read all the sensors. I do this on every cycle of my program which takes about 30 seconds. This program loops continuously 24/7. I have mentioned that a dictionary has been my best persistent storage method so far but since I am only doing this to learn OOP I’m open to all thoughts. I’m not clear what or how to implement your idea for averaging. I would like to try it.

obj instance 1 temp 10
obj instance 2 temp 15
obj instance 3 temp 20
obj instance 4 temp 25

i made a example app (2019r3.1) how i would do this.
https://drive.google.com/file/d/1NLHhFf5t3oFzSADrFIsIP7MaIxQPJZ_M/view?usp=sharing

Snap_2020.10.24_09h02m37s_001_Sensors

1 Like

Very impressive. Light years ahead of me on this but I’m working through it. Even though I do not need the listbox would you still use it as persistent storage? It seems to be integrated for averages.

In the sensors base class, I see a constructor. What would be the reason for that? Maybe the constructor in specialSensor overrides it. The construct method for all sensors’ names is great. I’m lost on IOSensor interface. Overload, time for breakfast.

AIUI, the constructor in the base class should do the general initialisation. You can either do all that instead in your subclasses Constructor, if you need to add to or override it, or just add extra code in those. But if the base class Constructor must be called, you have to call it thus:

super.Constructor ()

in your own constructor

without listbox for a persistent storage it is better to use a property,
its in the window Sensors() but you can place it everywhere.
the averages i put direct to the sensor object as property type Average class.

if you set a superclass and create a object from your class it is somehow two objects in one.
as tim said you can init something in your base class. because properties with classes have no default value they would be nil and you need to create a object first. the opposite from Constructor is the Destructor Method.

a interface is good if you need consistent methods in all classes.

Can you tell me anything more about the IOSensor class interface? It’s difficult for me to see how it is being used or what it does. I do see that the IOSensor aggregate is set for both Sensor and SpecialSensor. I have yet to use a class interface so I am not clear how they work. I believe it will not have any code and needs to be subclassed. I looked for an XOJO video but did not find one. Maybe some documentation exists somewhere.

if you set a interface at your class it make sure the defined methods are there, else you get a compiler error.
you create a interface it in the same way you would create a class.
you add a method name and his arguments and a return type if necessary.
https://documentation.xojo.com/getting_started/object-oriented_programming/interfaces.html
usually u use a interface if many classes need the same methods, and you have a benefit at for each.

A simple example. Say you have a class Cat and a class Dog. Knowing how different they are, of course, they don’t have any common super. Cat will have methods like Ignore() and SleepAllDay(). Dog will have methods like Walk() and Excitement(). Both will have a method Feed(). An interface allows you to write code like

var Pets() as PetInterface

var c as new Cat
c.name = "Fluffy"
Pets.AddRow(c)

var d as new Dog
d.name = "Spot"
Pets.AddRow(d)

for i as integer = 0 to Pets.LastRowIndex
    Pets(i).Feed
next

The interface allows you to take classes that are otherwise unrelated and treat them like the same thing.

Now even my partner understood that one. That helps to see how you create a common element.

1 Like