• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Override issue

 
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi folks,
I just read this question from our school BBS, could anybody give me some kind help?
 
Sheriff
Posts: 4313
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Have you tried to compile it? Check out the error message:
-------
C:\blah>javac Hide.java
Hide.java:29: Reference to test is ambiguous. It is defined in float test(float) and char test(char).
b.test('m'); //why compile error this line
-------
because the value of the character 'm' is 109 -- and that value can be interpretted as char or as a float. So the compiler doesn't know which version of the method test it should run.
[ May 20, 2002: Message edited by: Jessica Sant ]
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Notice, however, that the fact that the method invocation is ambiguous is dependent upon the fact that the test method is overridden in class Sub. Try commenting out that overriding method and see what happens.
Corey
 
luco zhao
Ranch Hand
Posts: 50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Corey McGlone:
Notice, however, that the fact that the method invocation is ambiguous is dependent upon the fact that the test method is overridden in class Sub. Try commenting out that overriding method and see what happens.
Corey



Yup, Corey is absolutely right. But could you please tell me the reason?
I've just done the following test, and it works without inheritence.
 
Ranch Hand
Posts: 5399
1
Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jessica Sant:

because the value of the character 'm' is 109 -- and that value can be interpretted as char or as a float. So the compiler doesn't know which version of the method test it should run.


But this is the case also with
b.test(1);
1 is char/int and can be widend to float also.
then why that is able to compile?
is it litral thats why ?
Now second question : passing 'm' as parameter for method which is suppose to take *char* is not good indication for compilar to not get confuse?
(true internally char are unsigned int)
CMIW
TIA
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmmm...This one is a tough one (it is for me, anyway). I've read through the first three sections of the JLS on Method Invocation Expressions. Those sections deal with compile time selection of the method to be invoked. Unfortunately, in no place (at least that I've seen) does the JLS come out and say why this doesn't work. However, I'll explain why I think it doesn't work and you can tell me I'm wrong however you'd like.
Step 1 of the process is to determine which class or interface to search for the method. From the JLS:


If the form is Primary . Identifier, then the name of the method is the Identifier and the class or interface to be searched is the type of the Primary expression.


So, from that, we know that we'll search for the method within the class Sub. Next, we need to search for all methods that are applicable and accessible. This is where the problem occurs, I believe. From the JLS:


The class or interface determined by the process described in �15.12.1 is searched for all method declarations applicable to this method invocation; method definitions inherited from superclasses and superinterfaces are included in this search.


I don't think the problem occurs in this step, but I think it originates here. In the next step, we need to locate the "most specific method." I believe the compiler gets confused as to which class to look in to find the most specific method. That's why it complains of ambiguity. Let's look at the following code and see what happens when we make small changes to it:

Compiled as it is, this code generates a compiler error. However, if you comment out the test method in the class Sub, you'll get the following output:

Notice that, even though there are two applicable and accessible methods within Super, the compiler chooses the method that takes a char because it is the "most specific." From this, I thought it was an issue dealing with method overriding but, I tried leaving the test method in Sub and commenting out the test method in Super. This leaves the code looking like this:

However, compiling this code also leads to a compiler error (due to ambiguity) even though there is no overriding taking place.
My best guess is that, because the compiler finds two applicable and accessible methods in two separate classes, it can not choose the most specific, even though it has no problem doing so when the methods are contained within the same class.
That's my best explanation of what is occuring. Sorry I can't be of more help. If anyone can explain, definitively, what is occuring, I'd love to hear it.
Corey
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Applying JLS 15.12.1 we agree that Sub is the class to search for the method declaration.


because the value of the character 'm' is 109 -- and that value can be interpretted as char or as a float. So the compiler doesn't know which version of the method test it should run.
But this is the case also with
b.test(1);
1 is char/int and can be widend to float also.


The words of Jessica must be interpreted in the context of JLS. Anyway, "1" is an "int" and as such it can not be widdenning converted to a char. Thus compiler has no problem about this call.

The key to understand this is JLS 15.12.2.2


The precise definition is as follows. Let m be a name and suppose that there are two declarations of methods named m, each having n parameters. Suppose that one declaration appears within a class or interface T and that the types of the parameters are T1, . . . , Tn; suppose moreover that the other declaration appears within a class or interface U and that the types of the parameters are U1, . . . , Un. Then the method m declared in T is more specific than the method m declared in U if and only if both of the following are true:
* T can be converted to U by method invocation conversion.
* Tj can be converted to Uj by method invocation conversion, for all j from 1 to n.


Consider the first list where we have two method declarations be chosen as the most specific:
Super.test(char) //inherited in Sub
Sub.test(float) // declared in Sub
None of them are most specific than the other. Because considering the types of the parameters, char is widdening convertible to float, BUT super is not to Sub.
This is so even if test(float) is not overriden as Corey's code showed.
Now the situation where the two methods are declared in Super, but not overriden in Sub:
Super.test(char)
Super.test(float)
char can be converted to float by widdening, AND Super can be concerted to Super by method invocation conversion (the same type or a widdening conversion). Thus there is a most specific declaration, and compiler doesn't complain.
 
Corey McGlone
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Jose Botella:
None of them are most specific than the other. Because considering the types of the parameters, char is widdening convertible to float, BUT super is not to Sub.


What did you mean by that? I lost you along the way.
Corey
 
Jose Botella
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
char is widdening covertible to float, but we cannot say that the declaration of
Super.test(char)
is more specific than
Sub.test(float)
because Super is not the same type or widdening covertible to Sub.
Follow the quote of JLS 15.12.2.2 . It speaks not only about the types of the parametes, but also about the types in which were placed the methods declarations we are considering.
Just post again if not clear enough.
 
reply
    Bookmark Topic Watch Topic
  • New Topic