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: 

May inheritance be a good trick to avoid nested classes serialized accessors?

Hello everyone,

This is not actually a question about a specific piece of code, but rather a discussion on a general programming technique.

The situation is as follows: I'm coding with OOP, and I have a data structure that includes nested classes, as exemplified in the attached picture Nested classes.png (let's say level 1 = A class, level 2 = B class, level 3 = C class); this means that if I need to write data of C class I have to create the following code (see the attached snippet Example.png; an A class is stored in a dedicated Data Value Reference):

  • Open the DVR and read B through an accessor of A;
  • Read C through an accessor of B;
  • Write the data or C I need through an accessors of C;
  • Write C into B through an accessor of B;
  • Write B into A through an accessor of A and close the DVR.

What I was wondering about is if I can make B inherit from A and C inherit from B in order to need just a single level of accessors whichever of the three classes I need to edit. This thought raised after coming across some class hierarchy trees with lots of child levels on the web (see attached pictures LV class hierarchy 1.png and LV class hierarchy 2.png), whereas I've never coded more that 1 level of inheritance before.

For example, let's imagine the following structure as it would be with nested classes:

  • Car.lvclass
    • General car properties (model, registration date...)
    • Array of Tyre.lvclass
    • Gearbox.lvclass
      • Array of Gear.lvclass
      • Etc.
    • Engine.lvclass
      • Array of Cylinder.lvclass
      • Shaft.lvclass
      • Etc.
    • Others

If I create an inheritance tree as I supposed before I would possibly be able to type-specify an instance of Car.lvclass into Tyre.lvclass in order to edit tyre properties without needing to read element of tyre + write tyre properties + write element of tyre (even more so for gears and cylinders).

What puzzles me is this: with such an approach, how can I specify that Car.lvclass is composed of exactly 4 elements of Tyre.lvclass, 1 element of Engine.lvclass that includes 4 elements of Cylinder.lvclass and so on, without duplicating the general information about the car (model, etc.) for each instance of a child class? Or, in other words, how can I keep track of the logical data structure of my system? And also, are there other drawbacks in this technique that I am currently missing?

 

If someone has experience with something similar, any contribution will be appreciated.

0 Kudos
Message 1 of 8
(2,764 Views)

I think it would be a terrible idea.

 

There are three relations in OO: "Is a ...", "Has a ...", and "Uses a ..." . "Is a ..." is typically inheritance.

 

If you can't say "Class B is a Class A", you should not use inheritance. A car is not 4 tires, so inheritance does not make sense. A car has 4 tires, so containment makes sense. These are not rules that are enforced, but if you go against them, your swimming up the stream (e.g. lots of work, little progress).

 

I'd try to get rid of the DVR's, they are usually a great idea until they become annoying (need an init, hard to debug, not persistent, extra code to access).

 

But if you do "allow" DVR's, you can make C objects use a DVR. Then you could keep a list of C's, and embed them in B, and embed B in A. Since C works by reference, you can change them from the list, and they will be modified in B as well, since they are the same object. Not my cup of tea, but it will work.

 

This is not the required way to do it (it's just how you chose to do it):

  • Open the DVR and read B through an accessor of A;
    • Read C through an accessor of B;
      • Write the data or C I need through an accessors of C;
    • Write C into B through an accessor of B;
  • Write B into A through an accessor of A and close the DVR.

You can also (using Car, Engine, Shaft as example):

  • Tell Car to change Shaft (by calling a method Car.Change Shaft);
    • Car tells Engine to change Shaft (by calling a method Engine.Change Shaft);
      • Shaft changes itself (by calling a method Shaft.Change Shaft);

This does indeed mean changing anything in the lowest contained class (Shaft), requires methods in all owners (Engine and Car). You can do (complex) things to prevent that, but usually this works fine. It works fine because it's simple and reflects reality.

 

Alternatively:

  • Tell Car to return it's Shaft (by calling a method Car.Get Shaft);
    • Car tells Engine to return it's Shaft (by calling a method Engine.Get Shaft);
  • Shaft can be changed outside Car and Engine;
  • Tell Car to replace the Shaft (by calling a method Car.Replace Shaft);
    • Car tells Engine to replace the Shaft (by calling a method Engine.Replace Shaft);

This is also simple and reflecting reality, just a different reality. It's almost how a mechanic would do it (he won't actually tell the car to return the engine, but anyway).

 

Just try to pick a winning method and try to stick with it. Mixing these techniques can really confuse a program.

 

 

Message 2 of 8
(2,745 Views)

First of all, thanks for the time you spent on this. I started reasoning about that possibility because otherwise it would not be easy to me to figure out which application may have so many levels of inheritance as the ones exemplified in the two LV class hierarchy that I attached in my first post, so I thought maybe those programmers made that for a purpose that may have been slightly different from pure inheritance; it was an hypothesis I tried to proof here.

0 Kudos
Message 3 of 8
(2,732 Views)

@Cente90 wrote:

First of all, thanks for the time you spent on this. I started reasoning about that possibility because otherwise it would not be easy to me to figure out which application may have so many levels of inheritance as the ones exemplified in the two LV class hierarchy that I attached in my first post, so I thought maybe those programmers made that for a purpose that may have been slightly different from pure inheritance; it was an hypothesis I tried to proof here.


The resolution of the first hierarchy is not high enough to read. The second one seems to have pretty pure inheritance.

 

Note that inheritance is just one way to specialize. If all those child DAQ devices (hierarchy 2) are almost the same (childs only added for "purity") an enum in their parent might have been a better choice.

0 Kudos
Message 4 of 8
(2,724 Views)

Yep, you are definitely describing a "Has a" relationship, which means composition is the proper relationship.

 

I highly recommend this book if you really want to use OOP effectively: The Object-Oriented Thought Process

 

As far as multi-level inheritance, I have not ran into the situation yet in the real world.  I can imagine a few situations where it could be used though.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 5 of 8
(2,711 Views)

@crossrulz wrote:

 

I highly recommend this book if you really want to use OOP effectively: The Object-Oriented Thought Process


One of the good books. I can also recommend Object-Oriented Analysis and Design, Booch. I'd buy a used copy, or 2nd printing for only a few $ (few good chapters (UML) missing though).

 


@crossrulz wrote: 

As far as multi-level inheritance, I have not ran into the situation yet in the real world.  I can imagine a few situations where it could be used though.


I use multi level inheritance at more then a few places. No problem.

 

I think the problem here is multi level containment. That can be a pain. If it makes you feel better: imagine doing anything similar without OO...

0 Kudos
Message 6 of 8
(2,698 Views)

wiebe@CARYA wrote:

I use multi level inheritance at more then a few places. No problem.


Never said it would be a problem.  Just stating that it is not exactly common in test oriented systems.  Again, that is based on my experience.

 


wiebe@CARYA wrote:

imagine doing anything similar without OO...


*shudder*


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 7 of 8
(2,692 Views)

@crossrulz wrote:

wiebe@CARYA wrote:

I use multi level inheritance at more then a few places. No problem.


Never said it would be a problem.  Just stating that it is not exactly common in test oriented systems.  Again, that is based on my experience.


I figured "situation"="problem". I'm not working on typical test systems, but test systems non the less.

0 Kudos
Message 8 of 8
(2,689 Views)