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);
}
}
class C2 extends C1 {
public void m1(int num) {
System.out.println("Inside C2.m1(): " + num);
}
}
And it is my main:
public class Main {
public static void main(String[] args) {
C1 c = new C2();
c.m1(10);
}
}
And the result was:
Inside C1.m1(): 10.0
When I expected:
Inside C2.m1(): 10
Also when I try to complete the code syntax, I found this:
Where is the other m1 of C2 class?
I also check the bytecode of my Main.class and I saw this:
Compiled from "Main.java"
public class com.company.Main {
public com.company.Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class com/company/C2
3: dup
4: invokespecial #3 // Method com/company/C2."<init>":()V
7: astore_1
8: aload_1
9: ldc2_w #4 // double 10.0d
12: invokevirtual #6 // Method com/company/C1.m1:(D)V
15: return
}
The bytecode tell me that it will invoke the C1.m1 (D)V (line 12).
Why the method of C1? I am trying to understand this behavior.
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. Frommain()
you actually calledC2.m1(double num)
.Note: Now at class
C2
you have two overloaded methods -m1(int num)
andm1(double num)
. AndC2.m1(int num)
is a different method fromC2.m1(double num)
.Method signatures for both methods are different.
So there is no overriding in this case. Now when you say
at compile time, it will se reference is of type
C1
which has methodpublic 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).By looking at your code, you are not taking advantage of inheriting to get the answer you want. You have to change this line
to
The reason why you see the output as
Inside C1.m1(): 10.0
and notInside C1.m1(): 10
orInside C2.m1(): 10.0
is because :m1
inC2
. You are overloading them1(doube)
method that you inherited fromC1
tom1(int)
instead.C2
class now has twom1
methods. One that isinherited
fromC1
and has the signaturem1(double)
and one that is overloaded inC2
and has the signaturem1(int)
c.m1(10)
, it resolves this call based on the reference type. Since the reference type isC1
, the compiler is going to resolve this call tom1(double)
inC1
.m1(double)
inC2
which is the method inherited fromC1
. (As explained in point 2)There are two ways in which the
m1(int)
method can be called :((C2)c).m1(10);
OR
C2 c = new C2(); c.m1(10);