aspose file tools*
The moose likes Beginning Java and the fly likes Why is the compiler confused? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Why is the compiler confused?" Watch "Why is the compiler confused?" New topic
Author

Why is the compiler confused?

Doanh Nguyen
Ranch Hand

Joined: Dec 02, 2000
Posts: 45
//Code segment A: Overload methods in the SAME class: Compiler is clear

(edited by Cindy to format code)
[ April 19, 2002: Message edited by: Cindy Glass ]
Dirk Schreckmann
Sheriff

Joined: Dec 10, 2001
Posts: 7023
Good question.
Cindy and Junilu answered it well a while ago.
As a tip for researching topics: I ran across this answer by doing a search on the forums at JavaRanch for "ambiguous". The search page link is at the top right of this page. Lots of great information can be found in the thousands of past conversations.
Good Luck.
[ April 19, 2002: Message edited by: Dirk Schreckmann ]

[How To Ask Good Questions] [JavaRanch FAQ Wiki] [JavaRanch Radio]
Junilu Lacar
Bartender

Joined: Feb 26, 2001
Posts: 4456
    
    6

Good question!
Note that the compiler is complaining about the method call: jav.m1(2), not the method declarations themselves. Without the method call the overloading is syntactically legal and the code will compile fine.
The problem comes when you try to invoke the overloaded method. The call is ambiguous because while the literal 2 is implicitly an int and would match the inherited m1(int), an implicit widening conversion could also be done so the overloaded m1(long) also matches!
To tell the compiler you want to call the overloade m1() in class Java (poor choice of class name, BTW), you can write either:
jav.m1(2L); // or
jav.m1((long)2);
But what if you want to call the m1 in class A? You might try to write
jav.m1((int)2);
but this won't compile because it's still ambiguous. What will work is if you cast the object reference like so:
((A)jav).m1(2);
This will invoke m1(int).
What is the reason for this behavior? I think the reasons have to do with implications of polymorphism and the OO design principle formally known as the Liskov Substitution Principle (LSP) that states (roughly) that "you should be able to substitute any reference of a superclass with that of a subclass".


Junilu - [How to Ask Questions] [How to Answer Questions]
Doanh Nguyen
Ranch Hand

Joined: Dec 02, 2000
Posts: 45
Thanks for all replies on this interesting issue.
Someone pointed out that when the subclass overloads a method with a narrower signature the compiler is OK.
This behavior reminds me of the restriction imposed on subclasses not to throw a wider exception than the superclass.
Maybe Java is consistent after all.
//Code segment B: Overload methods in the RELATED classes: Compiler is OK because the subclass has a narrower signature
class A{
void m1(long i){System.out.println("method long");}
}
public class Java extends A {
void m1(int i){System.out.println("method int");}
public static void main(String[] args){
Java jav = new Java();
jav.m1(2);
}
}
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Why is the compiler confused?