Search code examples
oopinheritancelabview

LabVIEW OOP: initializing parent from child


Question

How do I set up my classes in LabVIEW so that I can keep all of the common data between different child classes in the parent class and still initialize that data from the Initialize(data) method of the child class?

Background

I have a fairly large project in which I am using LabVIEW object-oriented programming (LVOOP) tools to simplify some things. I have a class tree that looks something like this:

representative class tree

Ideally what I would like to do is to keep all of the data that is common between all of my things in the GenericThing class, but then initialize this data along with the class-specific data in unique Initialize(data) methods for ThingType1 and ThingType2. Since the class-specific data is different between the two classes, and this data needs to be initialized, I cannot use the same signature for all of my Initialize(data) methods.

In Java I can do something like this:

class abstract GenericThing {
  protected String name;
  public GenericThing(String name) {
    this.name = name;
  }
}

class ThingType1 extends GenericThing {
  private int awesomeness;  // additional data
  public ThingType1(String name, int awesomeness) {
    super(name);
    this.awesomeness = awesomeness;
  }
}

class ThingType2 extends ThingType2 {
  private Boolean isSuperCool;  // different additional data
  public ThingType2(String name, Boolean isSuperCool) {
    super(name);
    this.isSuperCool = isSuperCool;
}

But for the life of me I cannot figure out how to do something similar in LabVIEW.

Attempts so far

I have tried to approach this from a couple of angles. First I tried creating an Initialize(data) dynamic dispatch method in my GenericThing class and then overriding it in the child classes, but this gives an error if you try to change the signature of the method (different inputs/outputs):

fingerprint mismatch error

OK, so I can't do it that way. Next I tried making data member access methods for the GenericThing class and calling them from the child class, but I cannot figure out how to call them in a way that actually sets data persistently. My attempt:

Initialize method that does not work

Basically using the To More Generic Class VI to get a reference to the parent class and set its data using the member access method that I created for GenericThing. This version runs just fine, but when I try to initialize both the parent and child data and then read that data back (similarly using To More Generic Class and my data member access method to read the parent's data), I get nothing for the parent's data.


Solution

  • I figured out something that works while I was writing this, but this caused me enough of a headache that I didn't want to just abandon my post. I was almost there with the question. Basically when I initialize the GenericThing data in ThingType1's Initialize method, I need to re-cast the output of GenericThing's data member access method to a ThingType1 object, initialize its data as well, and then pass that out like so (Edit: I do not need to recast this data. I can just directly pass the child-type reference into the parent-type method. Block diagrams updated below):

    Working Initialize method

    I can similarly pass the child-type reference directly to my parent-type method in the Get Data method:

    Working Get Data method

    And finally, I can initialize and read my data by calling these methods from a VI:

    Working test VI block diagram

    The result of running it with some random input values:

    Working test VI front panel

    Tadaa! Let me know if you have a better way of doing this.

    Update

    I updated my block diagrams based on some feedback in the comments. This makes one big improvement to my attempt at fixing my problem: I can directly wire the child's reference into the parent-type methods without dealing with the up-casting/down-casting syntax that was cluttering up my diagram!