From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Subclasses inheritance

Solved!
Go to solution

Hello everyone,

 

I have two classes "Datahandler.lvclass" and "Input.lvclass" and I am trying to understand the inheritance of the methods and variables.

I can access data of the Parent class and add it to the 'Child' using the methods of the 'Parent' (syncdata.png)

 

datatransfer.png

Is there a way to add all the data (and references) from the 'Parent' (merge classes, sync)? I have some notifiers in the 'Parent' and I would like to activate them in the child (since they have the same data but not the correct references)

 

Also some methods from the 'Parent' are not allowed to pass the datalines from the 'Child' (datatransfer_broken.png).

datatransfer_broken.png

Is there a special classification to pass them to the child? The method from the picture above seems to have no problem passing the datalines and are created using the same template (create using dynamic dispatch vi

0 Kudos
Message 1 of 28
(3,803 Views)

I'm not exactly sure what you're asking for so I'll describe some aspects of inheritance, hopefully it will help or at least lead you to describe what you want that I missed.

 

  • All classes have private data. Nothing that is not part of the class can directly access this (MyClass.ctl contents)
  • Classes can create accessor methods (this can be done by choosing New > VI for Data Member Access). This allows something else to access (read or write or both) the private data elements
  • VIs (and controls) in a class have access scope: Public, Private, Community or Protected
    • Public means anything can use it
    • Private means nothing can use it from outside of that class
    • Community means only this class, or friends of the class (configured via the Properties page of the class) can access it
    • Protected allows the class, or any children of the class, to access the method. This could be a good choice for e.g. template method patterns.
  • Children cannot generally access the data of their parents directly. They can make use of Protected data access VIs.
  • A public/protected VI can provide whatever data you want (from the parent) and be used by the child to get that data.
  • A wire has a specific type. If I wire two different children into a Build Array node, the wire type at the output is <array of parent.lvclass>.
  • If the wire type is a Parent.lvclass, then VIs specific to the child (i.e. not dynamic dispatch defined in the parent) cannot be called without a "To More Specific Class" node.
    • This is because the wire type doesn't know anything about that VI (it is a member of the child, not the parent)
    • It doesn't matter if the actual object on the wire is/might be a child1.lvclass, you still can't call Child1.lvclass:MyStaticVI.vi (at least without To More Specific)

Does this help at all?


GCentral
Message 2 of 28
(3,784 Views)

That helped a lot. 

 

Now my only problem is the initial synchronization. I write some data in the 'Parent'  (defined in Parent.ctl). Is there a way to get whole Cluster and not all the indiviudal elements.

 

When I unbundle the Parentdataline (in a dynamic dispatch method) I only get the individual elements and not the Cluster with all elements. I would like to transfer all the Parent data to the Child and not make individual lines for every entry

0 Kudos
Message 3 of 28
(3,766 Views)

@s.h._tech wrote:

When I unbundle the Parentdataline (in a dynamic dispatch method) I only get the individual elements and not the Cluster with all elements. I would like to transfer all the Parent data to the Child and not make individual lines for every entry


Then don't unbundle it. 😜 

You can make accessor on cluster level or even make custom ones.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 4 of 28
(3,762 Views)

You could create a typedef containing a cluster that contains all of the elements, and then either directly place that cluster inside the class data of the parent (adding an extra unbundle all the time) or alternatively add a static dispatch method that unbundles the elements individually, then bundles them into this typedef'd cluster, and returns that.

 

The second option (not necessarily better):

example.png


GCentral
0 Kudos
Message 5 of 28
(3,761 Views)

That means I have to add every value from the Parent manually to the child?

0 Kudos
Message 6 of 28
(3,748 Views)

@s.h._tech wrote:

That means I have to add every value from the Parent manually to the child?


Hmm, no. Probably not, anyway. What do you want to do with the values, once you have them in the child?

You initially mentioned notifiers, so there are possibly alternatives (like using a parent VI that can be called by the child, and passing appropriate data or state from child to parent).


GCentral
0 Kudos
Message 7 of 28
(3,741 Views)

@s.h._tech wrote:

That means I have to add every value from the Parent manually to the child?


What? no.

 

Every Child is also a parent. If you add everything from the parent to the child you now have it twice. Once in the parent and once in the child.

 

Think of it in terms of clusters. You have a cluster which contains data. This is your parent. Now you make a child. The cluster for the child contains also data (different to the parent) but also a data field which represents the parent. The trick is that you don't have DIRECT access to this data field as a child, but your Parent implements accessory to grant you access. If you need tha data from the parent, use parent accessors. Don't double-up your data fields.

0 Kudos
Message 8 of 28
(3,719 Views)

They are just there for initialization. 

 

I think I figured it out:

  • Initial values are copied manually from parent to child
  • All parentmethods that do not allow the childclass wire are newly generated (dynamic dispatch vi again) and for some reason they now allow the childwire (maybe a bug, or because it was generated before the subclass methods)

 

 

0 Kudos
Message 9 of 28
(3,714 Views)

@s.h._tech wrote:

They are just there for initialization. 

 

I think I figured it out:

  • Initial values are copied manually from parent to child
  • All parentmethods that do not allow the childclass wire are newly generated (dynamic dispatch vi again) and for some reason they now allow the childwire (maybe a bug, or because it was generated before the subclass methods)

It doesn't really sound like you're figured it out to be honest.

If you have initialisation for a parent which is only setting internal values then use the parent method for the child.

If your child needs a different initialisation, make a separate method for the child. Then call one after the other.

 

Can you post some example code of what you're trying to do?

0 Kudos
Message 10 of 28
(3,704 Views)