Let's say I have a situation as follows:
A class X
has a field s
of type S
.
S
is extended by two classes A
and B
both implementing some same methods/fields that we all know should then be implemented in S
but, unfortunately, this is not the case.
Now I want to do something like this:
"A or B" downcast_field;
if(s instanceof A)
downcast_field = (A)s;
else if (s instanceof B)
downcast_field = (B)s;
//do something common for the two cases but that need methods implemented both in A and B
The problem is then having in advance a static type (out of the IFs
) that allows me to call such methods.
I guess that due to bad design this is actually impossible and I have to write twice the same code, which is ugly, but perhaps there is a solution that I am not seeing right now.
If you can change A
and B
, then you can add the same interface to both. That would allow you to give this type to downcast_field
and invoke methods.
If you can't change A
and B
, then you have two options:
You can write A2
and B2
. Copy the code from A
and B
into the new types. That allows you to modify the code (unless you can't control the creation of those types). Alternatively, you could also now create S2
which extends S
and put the common code in there and then extend A2
/B2
from that.
Create an interface and then two implementations which just delegate the calls to the real type.
In this solution, you can
Wrapper downcast_field;
if(s instanceof A)
downcast_field = new AWrapper( (A)s );
else if (s instanceof B)
downcast_field = new BWrapper( (B)s );
downcast_field.foo();
You can make the two wrappers extend the same type and move common code there.