Meaningless Drivel is fun!*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Confusion!! Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Confusion!!" Watch "Confusion!!" New topic
Author

Confusion!!

Junaid Bhatra
Ranch Hand

Joined: Jun 27, 2000
Posts: 213
Consider the following code:
class Base
{
public void amethod(double d)
{
System.out.println("Base Method");
}
public static void main(String [] args)
{
Base o = new Derived();
o.amethod(10);
}
}
class Derived extends Base
{
public void amethod(int i)
{
System.out.println("Derived Method");
}
}
It prints out "Base Method" instead of "Derived Method"! Can anyone explain why this is happening?
Herbert Maosa
Ranch Hand

Joined: May 03, 2000
Posts: 289
Hie Junaid,
I hope you realise that amethod() is not overriden in the derived class, but it is overloaded.This has the effect of making two overloaded methods available to your derived class:
[ul]
  • void amethod(double d)//by inheritance
  • void amethod(int i)//by overloading above method
    [/ul]
    so when you invoke o.amethod(10), you present a very clear case of ambiguity to the VM because both the above methods can take 10 as a valid parameter value(10 can fit in an int as much as it can fit in a double).So the VM has tough time to decide which of your two methods to actually invoke;the general expected behaviour is to invoke the one which involves less overhead, which in this case would be the one expecting an int,for this would not involve any conversion; but the question is:Is this expected behaviour guaranteed,in all cases?, I dont think it is, and the results can be quite undeterministic,IMHO.
    If anyone knows of guaranteed behaviour, in such cases of ambiguity, let him/her help us out.
    Regards,
    Herbert
  • thomas
    Ranch Hand

    Joined: May 26, 2002
    Posts: 79
    The reason is the type of the reference to which the object is assigned to. Here, the type of the reference variable o is Base. Using this reference, you can only call methods defined in the Base class. If a method in the Base class is overridden in the Derived class, then dynamic method lookup will ensure that the overriding method is called. But in this case, the method amethod(double d) is NOT overridden in the Derived class. Hence the method in the Base class is called.
    Try after changing the type of the reference variable to Derived like this:
    Derived o = new Derived();
    o.amethod(10); // will call the subclass method
    o.amethod(10.0); // will call the superclass method

    rajsim
    Ranch Hand

    Joined: May 31, 2000
    Posts: 116
    I agree with thomas.
    The rules for method invocation are very precisely specified
    in JLS2 (Draft) Section 15.12.
    1. compile time selection of method signature
    as variable "o" is of compile time type "Base", amethod(int)
    can not be invoked through "o" reference hence compiler will
    choose amethod(double).
    2. finding actual method to invoke
    amethod(double) is only available in "Base" hence it is invoked.
    However if you override amethod(double) in "Derived" class, it
    will be invoked.
    I hope my understanding is right. Feel free to correct me.

    [This message has been edited by rajsim (edited July 09, 2000).]
    Junaid Bhatra
    Ranch Hand

    Joined: Jun 27, 2000
    Posts: 213
    Thanks Thomas & Rajsim. Got the point. I was confusing between compile-time method signature determination & run-time invocation.
     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Confusion!!