Passing a superclass as a parameter to a method waiting for a subclass

I have an object tree that looks like

Ball / \ LegalBall IllegalBall 

And I have 2 methods:

 class o { AddBall(LegalBall l) AddBall(IllegalBall i) } 

in another class, I would like to do the following:

 o.AddBall(myBall); 

where myBall is of type Ball. And ask him to call the correct method depending on the subtype. Apparently I can't do this ... the arguments are not applicable.

Does anyone know how I can achieve what I want? Or if there is a good job around

thanks

EDIT: the application I'm trying to create is an object of type Scorecard for cricket. Therefore, depending on the type of ball that is bowling, various other elements must change.

my initial intention was to be able to specify the type of ball and the paths received from any user model, and then create a suitable ball like BallFactory, and then, for example, when I send the ball without a team, it will add value to the team’s score but also add value to the counter without balls. But when I give the same ball to Batsmens analysis in order to deal with it, it only needs to gain a value of-1 for all the batsmans.

I hope this is not a bad explanation for my initial intention.

+4
source share
8 answers

You can use the visitor template .

 class Basket { void AddBall(LegalBall l) { System.out.println("LegalBall added to basket"); } void AddBall(IllegalBall i) { System.out.println("IllegalBall added to basket"); } } interface Ball { void AddBall(Basket b); } class LegalBall implements Ball { void AddBall(Basket b) { b.AddBall(this); } } class IllegalBall implements Ball { void AddBall(Basket b) { b.AddBall(this); } } 

or make it more general:

 interface BallVisitor { void visit(LegalBall l); void visit(IllegalBall i); } interface Ball { void accept(BallVisitor v); } class LegalBall implements Ball { void accept(BallVisitor v) { v.visit(this); } } class IllegalBall implements Ball { void accept(BallVisitor v) { v.visit(this); } } class Basket implements BallVisitor { void visit(LegalBall l) { System.out.println("LegalBall added to basket"); } void visit(IllegalBall i) { System.out.println("IllegalBall added to basket"); } } 
+6
source

You should try to implement only one method:

 class o { AddBall(Ball b) } 

and try to rely on polymorphism for different behaviors with respect to different classes. Of course, the details depend on the implementation of the Ball hierarchy.

+3
source

You may (or may not) want (part of) the visitor template.

Add the Ball method:

 public abstract void addTo(oo); 

Implement LegalBall and IllegalBall as

 public void addTo(oo) { o.add(this); } 
0
source

Well, here is the visitor pattern, as mentioned above. If you cannot or do not want to modify Ball, LegalBall or IllegalBall, you can try to have one branch of the method based on the type of ball. Please note: if you add QuasiLegalBall later, this code will break. The general case that you are talking about is complicated, because the existence of LegalBall and IllegalBall does not interfere with the presence of balls that do not fit into the two types that you described (at least in terms of language).

 class o { public void AddBall(Ball b) { if (b instanceof LegalBall) {AddLegalBall(b); } else if (b instanceof IllegalBall) {AddIllegalBall(b); } else { /*error, new type of ball created*/ } } private void AddLegalBall(LegalBall b) { } private void AddIllegalBall(IllegalBall b) { } } } 
0
source

Use visitor template. Doing this without cumbersome was the subject of this question: Work with a static Java method sending Double Dispatch / Visitor without templates .

However, can you state your original problem? I mean, why do you need to have these two overloads for the Add method? Maybe you can solve it in a completely different way that you don’t need to rely on dynamic sending as a visitor template?

0
source

How do you expect him to find out which one to name? What distinguishes two methods from what you expect him to call one and not the other?

-1
source

I agree with the use of the visitor.

In addition, if you do not have access to the Ball hierarchy (access to the source code) or just do not need to change anything; You can change your client class and decide from there.

Bad, of course, you get a lot of if / elseif statements.

You will need to add a general method (add (Ball)) and from there call the rest. It is fast, easy and dirty.

:)

 public class Test { public static void main( String [] args ) { Ball ball = new IllegalBall(); Test test = new Test(); test.add( ball ); test.add( new IllegalBall() ); test.add( new LegalBall() ); } private void add( Ball ball ){ System.out.println("Generic method: I'll have someone handling this : " + ball ); if( ball instanceof IllegalBall ) { add( ( IllegalBall ) ball ); } else if( ball instanceof LegalBall ) { add( ( LegalBall ) ball ); } } private void add( IllegalBall ball ){ System.out.println("illega-ball: I won't do anything about it! " + ball ); } private void add( LegalBall ball ) { System.out.println("legal-ball: Hey this is legal I'll do my best!! " + ball ); } } class Ball {} class IllegalBall extends Ball {} class LegalBall extends Ball {} 

BTW, if you don’t have the link directly, the compiler will send it to the correct method, as in the last two calls.

As you can see, you just need to add the following code:

 private void add( Ball ball ){ System.out.println("Generic method: I'll have someone handling this : " + ball ); if( ball instanceof IllegalBall ) { add( ( IllegalBall ) ball ); } else if( ball instanceof LegalBall ) { add( ( LegalBall ) ball ); } } 
-1
source

The visitor pattern and similar solutions using callbacks, in this case, seem to just try to bend your code in such a way as to force the compiler to accept your erroneous class hierarchy.

I would keep the Ball type and make the property of this type legal / illegal. You will only have o.add (Ball), in which you check legal / illegal based on some properties or by a method like isLegal ().

If the above approach does not seem reasonable, then it is impractical to have one method for adding two (very) different types, and the subtyping you propose will not be possible.

-1
source

All Articles