Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

polymorphic method call from third class

Thread view: 
Juergen - 06 Aug 2006 10:34 GMT
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);
    }
}
Burkhard Hassel - 06 Aug 2006 11:59 GMT
> Hi,
> (snip)
[quoted text clipped - 3 lines]
>
> 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());
Juergen - 06 Aug 2006 13:03 GMT
> 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
Juergen - 06 Aug 2006 19:33 GMT
> Hi,
>
[quoted text clipped - 7 lines]
>
> 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);
        }
Burkhard Hassel - 07 Aug 2006 12:30 GMT
>>Hi,
>>
[quoted text clipped - 19 lines]
>             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");
    }
}


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.