Win a copy of Mesos in Action this week in the Cloud/Virtualizaton forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Why is the compiler confused?

 
Doanh Nguyen
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
//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
Posts: 7023
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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 ]
 
Junilu Lacar
Bartender
Posts: 7466
50
Android Eclipse IDE IntelliJ IDE Java Linux Mac Scala Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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".
 
Doanh Nguyen
Ranch Hand
Posts: 45
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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);
}
}
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic