02-03-2016 06:11 AM
When using LabVIEW OOP, I've had cases where I override a method from a class but I do not want to call my immediate parent's method (using the Call Parent Method Node), I need to call another parent's method a couple of layers up.
This could be implemented with an optional terminal on the Call Parent Method Node to which a class constant is wired.
Is there some way I can code this in the current version of LabVIEW?
02-03-2016 06:48 AM - edited 02-03-2016 06:49 AM
Have you tried to use the To More Generic Class node to cast your class to the one you desire and then invoke the method on that?
Naa! After more thought that is not going to work!
02-03-2016 07:24 AM
The official way to achieve something like this is setting all options like this:
Inheritance of (grand-parent) class:
Item Settings of (grand-parent) class:
Note that the second setting is to be set for each dynamic dispatch you want to use like this!
Please note that the call chain goes up to from the child to the grand-parent. That means that each addition in any parent class in-between will be executed.
Norbert
02-03-2016 07:44 AM
Hi Norbert,
I don't believe that this will allow a child class to call the grandparent method without invoking the parent method. How would I specify in the diagram that the grandparent's method is to be called? I tried casting it to the grandparent, then calling the grandparent's method and then casting back to the child, but LabVIEW complained about a recursive call. I take it that even though I cast it to the grandparent, it still invoked the most specific implementation (which happens to be the calling function and thus the recursive complaint).
An example of where this is useful is:
Grandparent class is MotorVehicle. This implements a method SelfCheck that checks low-level functions like oil level, oil temperature etc.
Parent class is Sedan. This overrides SelfCheck to first call the more generic SelfCheck, and then checks that 4 doors are closed and speed is under 120km/h.
Child class is StationWagon. It is 99% similar to Sedan, so instead of inheriting from MotorVehicle, we inherit from Sedan (thus saving us from recoding 100's of other methods implemented in Sedan) and we only override the 3 or 4 methods that distinguish StationWagon from Sedan. One of these is SelfCheck. I want to still check oil temp so I want to call MotorVehicle:SelfCheck(), but I want to ensure 5 doors are closed and speed is under 100km/h. So invoking Sedan:SelfCheck() also is not the intention.
Any thoughts?
02-03-2016 07:53 AM
As i wrote: All "in-between" methods will be executed. There is no way to call a grand-parent method without calling the "in-between" ones.
Norbert
02-03-2016 08:01 AM
Well then at least I know I should stop trying. I'll implement a work-around (maybe a counter passed into the call-parent-method that tells it how deep it should go before executing - not very elegant though as the parent shouldn't need to know about the child). Or maybe I'll split the method into two and keep the grandparent functions seperate (not perfect either). Will try a couple and see which works best.
Thanks
Anthon
02-03-2016 08:06 AM
Anthon,
as long as the parents in-between don't add code to the "call parent method" (as pre- or post-processing), there is no need to do anything.
If parents in-between have some pre-/post-processing you want to execute only for specific classes in the inheritance hierarchy, you could add a case structure around that code. The selector is connected to "Get LV class Name.vi" to identify classes you want that processing to take place.
Do not forget to add a Default case which covers the common use-case for "unknown" (most likely newly developed) classes.
Norbert
02-03-2016 08:11 AM
Thank you Norbert yes that sounds like a better way of doing it. It still means that the parent would need to have anticipated that this is a requirement for future child classes, or that the implementor of the child class has access to change the parent class' diagram, but al least it is a more readable way of implementing this functionality.
Anthon
02-03-2016 08:16 AM
Sounds to me like your hierarchy is problematic. If your inherits from the parent, it should technically behave as a parent (the relevant search term is the Liskov substitution principle).
To take your example, a station wagon by definition is NOT a sedan, so it shouldn't inherit from it any more than a hatchback should. It's hard to say what a correct solution would be, but an obvious one would be to say that the classes should actually be siblings which get the logic from the parent and the actual values from the children or that for a method like SelfCheck they should just check that all doors in the array of doors are closed, etc.
02-03-2016 12:37 PM
In addition to what tst said - remember that inheritance is about behaviour not things.