Jump to content

grandchild calling grandparent method


Recommended Posts

I have a class hierarchy with a grandparent that implements a message handler.  I have a child class that overrides the message hander to add additional parallel functionality but also calls the parent method to get the message processing functionality.

I now want to make a grandchild that also overrides the message handler method to implement different parallel functionality but still needs to call the grandparent implementation to get the message processing functionality. (I am doing this because I want to inherit some methods from the child in the middle.)

The problem is, the grandchild wants to call the child implementation when I use 'call parent'.  But I don't want this middle implementation, I want the grandparent's version.  I cannot simply place the grandparent's method because that dispatches back to the grandchild (making the method recursive).

I think I solved this by using 'to more generic' before the call to the grandparent's method and 'to more specific' after the call.  But in the grandparent's method, it calls message 'Do' methods that need the data on the wire to be from the grandchild.  Will the 'to more generic' call strip that data from the wire or will the call to the 'Do' inside the grandparent pass the object as the grandchild so when I cast it to the grandchild, it will work?

 

Hope that was not too convoluted.  Any help is appreciated.

 

-John

Link to comment

Wow that was a difficult read...

 

To More Generic doesn't change the run-time class on the wire, simply provide some compiler guarantees that the class can then be viewed as the parent.

 

Without sitting down with a strong cup of coffee - your solution sounds like it might work but it also sounds awfully complicated for what is basically an LSP violation in the hierarchy.

Edited by ak_nz
Link to comment

As ak_nz says, the “to more…†methods don’t change the objects.  What you need to do is move the grandparent functionality into a separate static method, and call that method from all three DD methods (grandparent, parent and child).   That way, the child can replace the parent functionality while still calling the grandparent code.

Link to comment

Yes.  Sorry for the verbose description.  I did end of making a test project to prove/disprove this and discovered that even though I cast my object from grandchild to grandparent and then called the method in the grandparent directly, it still tried to run the grandchild's implementation which results in recursion and the VI was halted at that point.  So, there does not seem to be a way to do this.

And the point about the static method is correct, but I don't have the option of modifying the grandparent class as it is a key part of the system architecture.

 

My setup is similar to Actor Framework.  There is a top level actor class that implements the message handler.  All children of this class add on additional functionality but in parallel call the parent method to get the message handling functionality.  This works well in most situations.

But, in my case, I implemented an Actor that has certain behaviors for one use case.  I then made a child of this actor that uses the same 'run' method but overrides some of the other methods inside the 'run' to customize the actor to a slightly different use case.

I now have a third use case that differs from the first actor enough that just overriding some of the methods that are part of the 'run' method will not meet my needs.  *BUT* it does need some of the same methods used in the second actor that I created to override some of the functionality.  I really wanted to inherit those methods but it looks like I will have to instead make a new actor that inherits from the top level and I will have to duplicate those parts that are in the second actor's class.  This is a case where multiple inheritance or maybe traits would be useful.  I guess I am SOL.

 

thanks for the help.

 

-John

Link to comment

The only way I can think of is to add a (public) boolean element to the Child to signal whether it should execute it's version of the overridden function as opposed to simply passing it on to the "parent".

 

It's dirty and feels wrong but might be a way out of your predicament.  I mean, which is MORE wrong, this construct or simply duplicating code?

Edited by shoneill
Link to comment

As I understand it your problem is having two child classes that are very similar except in some functionality. Your solution is to make one child inherit from the other so that you can benefit from the similarities, but this gives you problems when calling the parent, which forces you to make implementations in a parent or grandparent because of what the grandchild needs.

 

I've been there a few times, and honestly mostly hacked my way around it, but the elegant design for this (if possible) should be to put the functionality that differs between the two children in an aggregated class that is overridden depending on which child functionality is to be used. This gives only one child, behaving differently depending on which aggregated class it is using.

Link to comment

Sounds to me like your grandchild class should be a sibling, you will have some duplication of the common code. Either that or you need to refactor your structure to move the special functionality out of your parent class and into a seperate grandchild.

 

Alternately, so you don't have to change a bunch of code, insert a new class between your grandparent and parent. Place the common functionality in the new class.

Link to comment

And the point about the static method is correct, but I don't have the option of modifying the grandparent class as it is a key part of the system architecture.

 

Not sure I understand.  You wouldn’t be changing any functionality; your DD methods for grandparent and parent would behave as before, but you would have the ability to call the static method directly from the child.

Link to comment

Not sure I understand.  You wouldn’t be changing any functionality; your DD methods for grandparent and parent would behave as before, but you would have the ability to call the static method directly from the child.

The problem would be the static method would need to be part of the grandparent, which in this case is basically my version of 'Actor Core' for my architecture.  So, it is not the right place to make customizations for a particular use case.

 

I think the cleanest solution is to strip the functionality that is common to the grandchild and the class I wanted to have inherit from it into a separate standalone reuse VI.  Then I can call that from the override VI in the grandchild and from the new class that will be a sibling of the parent.

 

Thanks for all the suggestions.  It really helped me sort this out.

Link to comment

I don't think this will help anymore (you said you can't modify the grandparent) but I've found it handy in the past for what I think are similar situations. Its essentially a nice way to describe what the dr. was suggesting:

http://en.wikipedia.org/wiki/Template_method_pattern

 

Here your top-parent provides a public static method and a protected dynamic method. This gives defined places for a child to override behavior but also makes sure the public method does what you want, like catching errors or handling incoming messages. That way you separate the functionality specific to the logic/algorithm from the functionality specific to the child. Its a really handy pattern.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.