inherited method invocation

J

John N.

I have the following problem in which my program chooses to invoke one
of several competing methods, the chosen one not being the one I want.
Does anyone know whay?

I have:

interface A;
class ASub implements A;

interface B {
foo(A myA);
}

class BSub implements B {
foo(A myA);
foo(ASub myASub);
}

class C {
A myA;
B myB;

C(A myA, B myB) {
this.myA = myA;
this.myB = myB;
}

bar() {
myB.foo(myA);
}
}

main() {
ASub myASub;
BSub myBSub;
C myC = new C(myASub, myBSub);

C.bar();
}


Now, for some reason, bar() invokes BSub.foo(A myA) instead of
BSub.foo(ASub myASub). Can someone explain why? And perhaps suggest a
solution which is elegant (which i realize might involve rethinking
everything).

Thanks.
John
 
D

Daniel Dyer

Now, for some reason, bar() invokes BSub.foo(A myA) instead of
BSub.foo(ASub myASub). Can someone explain why? And perhaps suggest a
solution which is elegant (which i realize might involve rethinking
everything).


You would either need to define the attributes of C as being of the more
specific type or you would need to perform an explicit cast in the bar()
method. Neither approach is ideal because you lose the generality in the
implementation of C. Reflection might solve this but that certainly does
not satisfy your "elegant" criteria.

Your example is extremely abstract so it's difficult to suggest a better
solution without knowing what problem you are trying to solve. As a
general rule I avoid writing methods that have signatures that differ only
in the type of a parameter where one type is interchangable with the other
(if you see what I mean, I'm sure there's a better way to phrase it). As
your posting indicates, it can make the behaviour of the code less obvious.

Dan.
 
J

Joona I Palaste

John N. said:
I have the following problem in which my program chooses to invoke one
of several competing methods, the chosen one not being the one I want.
Does anyone know whay?
interface A;
class ASub implements A;
interface B {
foo(A myA);
}
class BSub implements B {
foo(A myA);
foo(ASub myASub);
}
class C {
A myA;
B myB;
C(A myA, B myB) {
this.myA = myA;
this.myB = myB;
}
bar() {
myB.foo(myA);
}
}
main() {
ASub myASub;
BSub myBSub;
C myC = new C(myASub, myBSub);


Now, for some reason, bar() invokes BSub.foo(A myA) instead of
BSub.foo(ASub myASub). Can someone explain why? And perhaps suggest a
solution which is elegant (which i realize might involve rethinking
everything).

Method overloading with different parameters is not polymorphic. It's
done entirely at compile time. Because the argument of foo() in bar()
is of type "A", the compiler will compile it to call the foo(A)
implementation, no matter what object that parameter refers to, be it
a normal A, a ASub, or some other subclass of A.
You'll have to do some sort of class checking with instanceof and then
call the appropriate method depending on the result. Somewhat like
this:

if (myA instanceof ASub) {
myB.foo((ASub)myA);
/* cast needed to make compiler realise it's a different overloaded
method */
}
else {
myB.foo(myA);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top