File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Method Overloading Question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Method Overloading Question" Watch "Method Overloading Question" New topic
Author

Method Overloading Question

Dpk
Greenhorn

Joined: Feb 14, 2000
Posts: 10
Few days back, I saw a posting in "javacert", i am still unable to understand the error, Can anybody help me in this ?
The following code (B.java) gives Compile error:
class A {
public void test(B b) {
System.out.println("A - public void test(B b)");
}
}
class B extends A {
public void test(A a)
{
System.out.println("B - public void test(A )");
}

public static void main(String[] args) {
B b = new B();
b.test(b);
}
}
The error is : Ambigious Call at b.test(b)
I thought this may be because of Polymorphism as B is subclass of A. So compiler is unable to decide between test(B b) and test (A a). But when i copied this method in class B also:
public void test(B b) {
System.out.println("A - public void test(B b)");
}
It compiled successfully.
Any inputs on this behaviour are appreciated ! TnX !
Thandapani Saravanan
Ranch Hand

Joined: Oct 17, 1999
Posts: 117
At compile time the Compiler needs to know which method is referred in a method invocation expression. In this code, the method invocation expression b.test(b) is ambiguous to the compiler. The compiler is not sure whether you are referring to test in A or B. This is because the compiler thinks that the parameter to test() could be A or B.
To make it clear, we can say b.test((A)b) if we want to call B's test() or say ((A)b).test(b) if we want to call A's test().
[This message has been edited by Thandapani Saravanan (edited February 13, 2000).]


Saravanan
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
To my knowledge, to give polymorphism behavour, overriding methods must be same in return type, name and parameter list(order and type). Since both the test methods had different arguement types, this is not overriding behaviour.
Now B b = new B();
In this case, the contents of the pointer is object B, so it will call test(B b) of class B.
Dynamic binding is always according to the contents of the reference variable not the type of reference variable.
Dpk
Greenhorn

Joined: Feb 14, 2000
Posts: 10
Thandapani, I agree, but if i am having test(B b) in class B also, compiler just do fine !!! Do not need any cast !
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Neetagupta is correct that the method profiles are different, and therefore overriding and polymorphism are irrelevant to this problem. It's about overloading - the compiler needs to be able to choose which of the overloaded method signatures is more appropriate to use. This is covered in detail in the Java Language Specification here. Basically the compiler tries to determine if one method profile is more specific than the others, and if so, that's the one to use. One method declaration is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error. In this case:
(assume a and b are instances of classes A and B respectively.)
"a.test(b)" could be handled by A.test(B) but not by B.test(A), so A.test(B) is not more specific than B.test(A).
"b.test(a)" could not be handled by A.test(B), but it could be B.test(A), so B.test(A) is not more specific than A.test(B).
Since neither method is more specific than the other, any invocation that could apply to both (i.e. "b.test(b)") is ambiguous, and causes an error.
If you also supply a B.test(B), then this new profile is more specific than the others, and any invocation that applies to B.test(B) (as well as the others) will indeed call B.test(B) without ambiguity.

"I'm not back." - Bill Harding, Twister
Dpk
Greenhorn

Joined: Feb 14, 2000
Posts: 10
Is it not overloading case, when b (class B type) is having test(B b) from class A, and also having same name method test(A a) of it's own ? Shouldn't rule of more specific apply here ? Why it gives Ambigious error ?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Dpk: yes, this is overloading, as I said. The rule about using the most specific method does apply here. The problem is that neither method is more specific than the other. Think of it this way: If there were a method A.test(A), that would be the least specific. If there is a method B.test(B), that's the most specific (the method invocation is "b.test(b)"). Both A.test(B) and B.test(A) are in the middle, and neither one is more specific than the other, so the compiler cannot choose.
Dpk
Greenhorn

Joined: Feb 14, 2000
Posts: 10
Jim:
Here Class B extends A.
so test(B b)(inherited from A) and test(A a) are both methods available to any object of type B ! So if i say b.test(b) Shouldn't test(B b) be the most specific and test(A a) the least?
thanks for your Patience !
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
But because test(B) is not defined in class B, it can never be considered more specific than another method that is defined in class B. That's just the way the rules are written (again, you can read them here). To summarize them another way: for a method to be more spcific than another method, it must (a) be defined in the same class or a subclass of the class that the second method is defined in, and (b) each of its arguments must be the same as the corresponding argument in the second method, or a subclass of it.
I used notation like A.test(B) as shorthand for "test(B) method defined in A" - sorry if I didn't make that clear.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Method Overloading Question