polymorphic method call from third class

J

Juergen

Hi,

can somebody please explain to me, why the output of the code below is
test(A)
test(A)

instead of
test(A)
test(B)

which I had expected?

It seems, Java only uses the dynamic type information for calling an
object's methods, but not if the class is a parameter of a third
class's methods.

Why is this so?

Thanks,
Juergen



package overloading;

public class Test
{
public class A {}

public class B extends A {}

private void test(A a)
{
System.out.println("test(A)");
}

private void test(B b)
{
System.out.println("test(B)");
}

public static void main(String[] args)
{
Test t = new Test();
A a = t.new A();
A b = t.new B();

t.test(a);
t.test(b);
}
}
 
B

Burkhard Hassel

Juergen said:
> Hi,
> (snip)
> It seems, Java only uses the dynamic type information for calling an
> object's methods, but not if the class is a parameter of a third
> class's methods.
>
> Why is this so?

Hi Juergen,
it has nothing to do with calling from a third class.
Both your objects a and b have the same REFERENCE type A:
> Test t = new Test();
> A a = t.new A();
> A b = t.new B();
>
> t.test(a);
> t.test(b);

When asking what method to call, the compiler looks for the reference
type, not for the objects type. So, test(A a) will be called twice.

The polymorphic behaviour you'd expected matters in overridden methods
only, e.g.

class A{
void test(A a){
System.out.println("A from class A");
}
void test(B b){
System.out.println("B from class A");
}
}
class B extends A {
void test(A a){
System.out.println("A from class B");
}
void test(B b){
System.out.println("B from class B");
}
}
class AB_User {
public static void main(String[] args) {
A a = new A();
B b = new B();
A mixed = new B();
// Output:
mixed.test(a); // -> A from class B
mixed.test(b); // -> B from class B
mixed.test(mixed); // -> A from class B
}

The "mixed" Object (Reference type A, Object type B) will
polymorphically call the methods from class B (not A), since they are
overridden here.
Which of the two methods are called depends only on the reference type
of the object handed over in the brackets.

BTW, your methods were marked private, and with private there would be
no polymorphy anyway.

Yours,
Bu.

___
String s = "sea anemone";
System.out.println(s.substring(5,9).toUpperCase());
 
J

Juergen

Burkhard said:
When asking what method to call, the compiler looks for the reference
type, not for the objects type. So, test(A a) will be called twice.

Thanks very much for the information. Somehow Java lessions only talk a
lot about shapes and circles, so I can't remember the the problem I
encountered being addressed. I tried to look up the method lookup
algorithm in the Java language specification, but it is everything but
trivial.

Juergen
 
J

Juergen

Juergen said:
Hi,

can somebody please explain to me, why the output of the code below is
test(A)
test(A)

instead of
test(A)
test(B)

which I had expected?

Is there a less cumbersome way to call the original method according to
the runtime of the parameter than

if (b instanceof A)
{
t.test((A)b);
}
else if (b instanceof B)
{
t.test((B)b);
}
 
B

Burkhard Hassel

Juergen said:
> Juergen wrote:
>
>
>
> Is there a less cumbersome way to call the original method according to
> the runtime of the parameter than
>
> if (b instanceof A)
> {
> t.test((A)b);
> }
> else if (b instanceof B)
> {
> t.test((B)b);
> }
>



Hi Juergen,

if the test-methods does not have to be private, you should make a class
A with the test method taking an A-type as a parameter.
In class "B extends A" override the method. You don't have a test-method
that takes a B-type at all, cause polymorphy should do the job. If B
extends A you can invoke the method in class B with an A type or a B-type.

Inner classes (as in your first example) are not necessary in that case.

If I understood you right, the test code could be as simple as shown below.

If the test-methods have to be private, you could use B as an inner
class of A, but then you'd need also a second (not-private) method that
invokes the private ones (code not shown).

So: Do your test-method has to be private?

Yours,
Bu.


____
// Example
class TestUser {
public static void main(String[] args) {
A a = new A();
B b = new B();
A mix = new B();
a.test(a); // -> Test A
b.test(b); // -> Test B
mix.test(mix); // -> Test B
}
}
class A {
void test(A a) {
System.out.println("Test A");
}
}
class B extends A {
void test(A a) {
System.out.println("Test B");
}
}
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top