• 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

Problem in Scope of Reference Variable.....

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,
can anyone tell me why this is giving compiler error???
public class work23 {
work23()
{
System.out.println("default");
}
work23(int i)
{
System.out.println("int");
}
work23(long l)
{
System.out.println("long");
}
public void draw(int j)
{
System.out.println("draw parent");
}
public static void main ( String a[])
{
work23 w = new work23(23);
child ch = new child(10);
ch.draw(10);
}
}
class child extends work23 {
child(int k)
{
System.out.println("child int");
}
public void draw(float ll)
{
System.out.println("drawing long child");
}
}
compiler is giving error as
Reference to draw is ambiguous. It is defined in void draw(float) and void
draw(int).
ch.draw(10);
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HI
The problem is with your
ch.draw(10);
either make it
ch.draw(10f);
or change the draw method in the child
from
public void draw(float ll)
to
public void draw(int ll)
I think this 'll solve your problem
 
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Jyothi,
At compile time, the compiler looks at two things and then decides which method is the most appropriate.
1. Determines Method Name.
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked. Here, the superclass is also searched for all method declarations applicable to this method invocation.
So, in the above mentioned example, since child2 inherits method draw(int j) from the superclass work23, this method is also considered.
NOTE:
If there were any more methods in superclass (e.g. draw(long l, short s), it also would have been considered at this point.
2. Determine Method Signature.
This step uses the name of the method and the types of the argument expressions to locate method declarations that are both applicable and accessible, that is, declarations that can be correctly invoked on the given arguments. There may be more than one such method declaration, in which case the most specific one is chosen. So, here method draw(long l, short s) will be dropped and we will be left with only two applicable methods draw(int j) and draw(float fl).
Now, how to find most appropriate? Here comes the ambiguity.
Find Methods that are Applicable and Accessible
A method declaration is applicable to a method invocation if and only if both of the following are true:
The number of parameters in the method declaration equals the number of argument expressions in the method invocation.
This is already considered.
The type of each actual argument can be converted by method invocation conversion to the type of the corresponding parameter.
When you say, ch.draw(10), the value passed is 10. 10 is a valid argument for both draw(int j) and draw(float f).

So both method satisfy all required conditions. Now, compiler is left with two methods draw(int j) and draw(float f). So, here the compiler is confused and cannot decide which method is more appropriate. You can solve this situation by calling ch.draw(10f).
There are other ways too, but then there is no question of method overloading here.
1. declaring draw(int j) as private in work23. This method will not be accessible to child class.
2. declare draw(int j) without any modifier and define child2 in another package. Here child2 should be in another package or else it will have access to parent method draw(int j). Remember, if you declare a method without any access attribute, it will be inherited(to be more precise accessible) by the derived class if and only if derived class is in the same package as the base class.
I hope this clears your doubt.
For detailed explanation refer JLS:
http://java.sun.com/docs/books/jls/html/15.doc.html#20448

Suma.

[This message has been edited by Suma Narayan (edited May 23, 2000).]
 
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Suma Narayan:
This is the case of method Overloading. Here, method draw(int j) defined in superclass is being overloaded with method draw(float fl) in the subclass child.



Suma:
That was a good explanation of the cause of the error and
how to fix it. However, I have a little concern with the
above stmt. IMHO, you have used the word overloading
in a wrong sense. My understanding (with 100 % confidence)
Overloading is in the SAME class.
Overriding in the sub-class class.
Since, the "child" class (not "child2") is called
a sub-class (due to the extends keyword), I would be
more comfortable with the use of overriding
rather than overloading.
Do I make sense?
Thanks.
- satya
 
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Satya,
Though the child class extends the work23 class, it is NOT overriding the draw() method. Overriding happens when the subclass defines the method with the same signature. As you can see what child class defines is public void draw(float ll) which is not the same as public void draw(int j).
Infact the draw method in the child class is just an instance method. It is not an overloaded method because there are no methods defined with the same name in child class. It is not overriding either because the signatures don't match.
Ajith
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

aha....
Yup, Ajith you are right. I missed out on this.
Suma sorry.
RHE explains ...(p173)
Overloaded methods must have different argument lists,
overriding methods must have argument lists of identical
type and order (otherwise they are simply treated as
overloaded methods.)

So, I think we can call them overloaded methods
in agreement to what RHE says in the () above.
Again sorry Suma, never thought the words in the () are so
important.
Regds.
- satya
 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No "sorry" allowed here on board. After all it is a learning experience for all of us. Perhaps JavaRanch should charge $1 for each sorry used in the postings.
Satya you already owe $2 !!
 
Suma Narayan
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Satya,
Yup. No sorry allowed. We are all learning. In fact I like what Ajith has suggested. So, satya you owe me $2. right!!
(Since i am a part of javaranch)
Ha! Ha!
Suma.
[This message has been edited by Suma Narayan (edited May 23, 2000).]
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Suma Narayan:
Hi Jyothi,
This is the case of [b]method Overloading.
Here, method draw(int j) defined in superclass is being overloaded with method draw(float fl) in the subclass child. At the compile time, the compiler looks at two things and then decides which method is the most appropriate.
1. Determines Method Name.
The first step in processing a method invocation at compile time is to figure out the name of the method to be invoked. Here, the superclass is also searched for all method declarations applicable to this method invocation.
So, in the above mentioned example, since child2 inherits method draw(int j) from the superclass work23, this method is also considered.
NOTE:
If there were any more methods in superclass (e.g. draw(long l, short s), it also would have been considered at this point.
2. Determine Method Signature.
This step uses the name of the method and the types of the argument expressions to locate method declarations that are both applicable and accessible, that is, declarations that can be correctly invoked on the given arguments. There may be more than one such method declaration, in which case the most specific one is chosen. So, here method draw(long l, short s) will be dropped and we will be left with only two applicable methods draw(int j) and draw(float fl).
Now, how to find most appropriate? Here comes the ambiguity.
Find Methods that are Applicable and Accessible
A method declaration is applicable to a method invocation if and only if both of the following are true:
The number of parameters in the method declaration equals the number of argument expressions in the method invocation.
This is already considered.
The type of each actual argument can be converted by method invocation conversion to the type of the corresponding parameter.
When you say, ch.draw(10), the value passed is 10. 10 is a valid argument for both draw(int j) and draw(float f).

So both method satisfy all required conditions. Now, compiler is left with two methods draw(int j) and draw(float f). So, here the compiler is confused and cannot decide which method is more appropriate. You can solve this situation by calling ch.draw(10f).
There are other ways too, but then there is no question of method overloading here.
1. declaring draw(int j) as private in work23. This method will not be accessible to child class.
2. declare draw(int j) without any modifier and define child2 in another package. Here child2 should be in another package or else it will have access to parent method draw(int j). Remember, if you declare a method without any access attribute, it will be inherited(to be more precise accessible) by the derived class if and only if derived class is in the same package as the base class.
I hope this clears your doubt.
For detailed explanation refer JLS:
http://java.sun.com/docs/books/jls/html/15.doc.html#20448

Suma.
[This message has been edited by Suma Narayan (edited May 23, 2000).][/B]



hi,
Consider the following snippet,
class a
{
public void fun(int i)
{
System.out.println("hai");
}
public void fun(float f)
{
System.out.println("hello");
}
public static void main(String asd[])
{
new a().fun(10);
}
}
Well, when i compile and run this code I get an output as "hai".
Even this is OverLoading why is that I am noting getting that
ambiguous error. Please clear my doubt.
Thanks in advance,
this is prasadh signing off for now.

 
Ajith Kallambella
Sheriff
Posts: 5782
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Prasadh,
The ambiguity in the first case was due to the fact that there were TWO versions of the draw method, one in the current class another in superclass, both being able to legally accept the value passed during the method invocation.
In your example, you are simply creating new overloaded methods and there are no overridden methods. So the compiler is
Hope this helps.
Ajith
 
Suma Narayan
Ranch Hand
Posts: 136
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ajith,


Infact the draw method in the child class is just an instance method. It is not an overloaded method because there are no methods defined with the same name in child class. It is not overriding either because the signatures don't match.


As per JLS
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but different signatures, then the method name is said to be overloaded. This fact causes no difficulty and never of itself results in a compile-time error.

Also, RHE says
In the class that defines the original method, or a subclass of that class, the method name can be reused if the argument list differs in terms of the type of atleast one argument.This is overloading.
So I think draw() is an overloaded method.
However, this has nothing to do with the ambiguity.
Hi Ram,
I think my statement of "It is a case of Method overloading" is bit confusing. I have a feeling that you are trying to relate compiler search for most appropriate method with overloading. This is not the case. I have edited my explanation and removed the above statement.
After reading JLS,this is what I think about the first example.
Here, we are trying to call method draw using ch.draw(10).
1.At compile time, the compiler will search the child class and look for method with the above name and number of arguments. It finds draw(float fl). But since it also searches for the base class(refer the link given for details), it gets another method draw(int j) which satisfy the name and the number of arguments.
2. Now, there are two methods to choose. Now to choose the most specific method, the compiler does the following
From JLS:
Choose the Most Specific Method
If more than one method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. Java uses the rule that the most specific method is chosen.
The informal intuition is that 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.
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.
A method is said to be maximally specific for a method invocation if it is applicable and accessible and there is no other applicable and accessible method that is more specific.
So as per above explanation, the compiler thinks that draw(int j) is maximally specific than draw(float fl) as the automatic conversion of int to float is possible and not the other way round. But we are trying to call the child class method. I think, here is where the ambiguity arises.
In your example, the compiler does the job and figures out fun(int ) is maximally appropriate and hence no error.

Does this explanation make more sense now??
I think I being more logical now.I may have interpreted it wrongly. I will wait for any inputs on this. I sure need a coffee break now.
Suma.

[This message has been edited by Suma Narayan (edited May 23, 2000).]
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
hi,

But i am not able to understand one thing.
draw(int) and draw(float) are two overloaded methods.
even if int version is defined in base class and float version is defined in derived class.AM i right??
Now if i define both int and float in derived class the compiler doesn't face the ambiguity problem.but when i define int in base and float in derived then only why the compiler is having the ambiguity problem as int is more specific so why the compiler is facing the problem.it should call the int version of draw even if it is defined in base class as derived class has access to that and it is inherited in the derived class
I am not able to get this point
Thanks,
jyoti
 
The government thinks you are too stupid to make your own lightbulb choices. But this tiny ad thinks you are smart:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic