Hi,
Consider this from JLS
8.4.7 Overloading 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. There is no required relationship between the return types or between the throws clauses of two methods with the same name but different signatures.
Methods are overridden on a signature-by-signature basis.
If, for example, a class declares two public methods with the same name, and a subclass overrides one of them, the subclass still inherits the other method. In this respect, the
Java programming language differs from C++.
[c++ is pretty clear on this, there's no overloading across classes unless you explicitly do it using "using ..." construct.]
NOW -
<code>
<pre>
public class A
{
public static void main(String[] args)
{
D obj = new D();
int i = 100;
double d = 100.1;
char c = 'M';
obj.m1(c);
obj.m1(i); //ERROR!!!
obj.m1(d);
}
}
class D extends B
{
public char m1(char c)
{
System.out.println("derived char " + c + " " +c);
return c;
}
public double m1(double d)
{
System.out.println("derived double " + (d + 1.1));
return d + 1.1;
}
}
class B
{
public int m1(int i)
{
System.out.println("base int " + (i + 1));
return i + 1;
}
}
</pre></code>
This gives comile time error, which says -
<code>
<pre>
Reference to m1 is ambiguous. It is defined in double m1(double) and int m1(int).
obj.m1(i);
^
1 error
</pre></code>
I have following questions -
(1) In class D, all three methods are accessible, while resolving the ambiguous call "obj.m1(i);", the most specific method (as per JLS) should be - public int m1(int i) which is both applicable and accesible, no promotion whatsoever is needed. So why ambiguity???
(2) There are two very interesting observations here -
Case 1 : If I override the method "public int m1(int i)" in class D(with or w/o changing the implementation), the thing comiles smooth and (understandably) invokes class D method.
NOW, since "public int m1(int i)" is very much accessible (and also applicable) in class D, why should this make any difference?
If I do not override it in class D, the base class implementation should prevail.
Case 2 : More interestingly, if I just comment method "public double m1(double d)" in class D, and calls to that method, it compiles and overloading is smooth across classes, ensuring that class B method is accessible, aplicable and hence used.
In presence of "public double m1(double d)" however things change, a method call "obj.m1(i);" is ambiguos. My question obviously is "WHY?". If it is due to promotion rule then I again have 2 doubts -
(a) When there is most specific method available for int argument - public int m1(int i) - in class D's scope, that's whwre the call should be resolved by the compiler, without any need of considering promotion.
(b)Again, even char can be promoted if needed, it is not an argument like bolean which is type incompatiable. Despite of this, a call to a method "obj.m1(c);" is resolved to the most specific case w/o any compile error.
So why a call to "obj.m1(i);", is not resolved to its most specific case which is both accessible and applicable. What am I missing? Where am I incorrect and/or inaccurate in my assumptions/understanding?
Could somebody pl. explain this in details?
TIA,
- Manish
[This message has been edited by Manish Hatwalne (edited October 01, 2001).]