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
If you call c.m1(10.0) it will call the method of the ancestor as you were expecting at first.
You're doing method overloading in your example (that is adding more methods with the same name and different signature) instead of method overriding (that is changing the implementation of an ancestor's method at a descendent by redeclaring it with the same signature, AKA same name and same type of result and of method arguments - argument names shouldn't matter).
You cannot see methods of C2, because you instance variable is declared as C1 and also because they don't have the same signature. You have double parameter in one method and in second a int type which makes them for JVM completely different methods (so no inheritance will work here).
So if you have int type in C1 method then you need to have also int type in C2 method, then JVM will run method from C2 like you wanted.
Also you can cast variable to C2 type then you will be able to access to methods of C2.
By looking at your code, you are not taking advantage of inheriting to get the answer you want. You have to change this line
C1 c = new C2();
to
C2 c = new C2();
The reason why you see the output as Inside C1.m1(): 10.0
and not Inside C1.m1(): 10
or Inside C2.m1(): 10.0
is because :
m1
in C2
. You are overloading the m1(doube)
method that you inherited from C1
to m1(int)
instead.C2
class now has two m1
methods. One that is inherited
from C1
and has the signature m1(double)
and one that is overloaded in C2
and has the signature m1(int)
c.m1(10)
, it resolves this call based on the reference type. Since the reference type is C1
, the compiler is going to resolve this call to m1(double)
in C1
. m1(double)
in C2
which is the method inherited from C1
. (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);