I do not understand this Java behavior. I have two classes:
class C1 {
public void m1(double num) {
System.out.println(\"Inside C1.m1(): \" + num
Java does method dispatch on static types, and your variable c
is of type C1
, so m1(int)
is not visible, and your 10
is cast to double
.
Your two methods named m1
do not have the same signature; the one in the superclass takes a double
, and the one in the subclass takes an int
. This means that the compiler will select the method signature to call based on the compile-time type of your variable, which is C1
, and will call m1(double)
. Since at runtime the class C2
doesn't have an overriding version of m1(double)
, the version from C1
is invoked.
The rule is that method signatures are computed at compile time based on compile-time types; method calls are dispatched at runtime based on matching signatures.
Since C1.m1(double num)
is a public method, it inherited C2. So your C2 also has a method, m1(double num)
, and that's why it is called. From main()
you actually called C2.m1(double num)
.
Note: Now at class C2
you have two overloaded methods -
m1(int num)
and m1(double num)
. And C2.m1(int num)
is a different method from C2.m1(double num)
.
It's because of the parameters. The method you call is a method with a double parameter. m1 inside of C2 is not overriding this, instead it's overLOADING it.
If you want to call m1 in C2, you have to cast the reference such that the compiler accepts what you're doing.
Method signatures for both methods are different.
public void m1(double num)
public void m1(int num)
So there is no overriding in this case. Now when you say
C1 c = new C2();
c.m1(10);
at compile time, it will se reference is of type C1
which has method public void m1(double num)
which is compatible with 10 [int in expanded to double]. So int is promoted to double, and the corresponding method is called (which is also what you see in the bytecodes).
Java chooses the most specific applicable type. In this case m1(int) is not applicable. Emphasis on the reference of class that hold object of same class(c1) or an object of any sub classes of class(c2) & method name and parameter list .
Your method with double parameters is being called because double takes priority over int. This is because an int can be assigned to a double, but not the other way around.
So there are so many things to be consider at the (run) time of method call.
Yes for ur case your main class should be like this
public static void main(String[] args) {
C1 c = new C2();
c.m1(10);
((C2) c).m1(10);
//or
C2 cobj = new C2();
cobj.m1(10);
}
**OutPut**
Inside C1.m1(): 10.0
Inside C2.m1(): 10
Inside C2.m1(): 10