public class Tester {
public static void main(String[] args) {
A a2 = new B();
a2.dosomething1(new B());
a2.dosomething2(new B());
}
}
class A {
public void dosomething1(A a){
System.out.println("Inside a dosomething1");
}
public void dosomething2(A a){
System.out.println("Inside a dosomething2");
}
}
class B extends A {
public void dosomething1(A a){
System.out.println("Inside b dosomething1");
}
public void dosomething2(B b){
System.out.println("Inside b dosomething2");
}
}
Output
Inside b dosomething1
Inside a dosomething2
The first line in output is clearly due to method overriding. But what is the reason behind second line ? Why java not calling the method defined in B as on runtime it knows a2 is object of B.
The question you need to answer is this: can B.dosomething2(B b)
fully replace A.dosomething2(A a)
? Or more specifically: can every parameter value accepted by A.dosomething2(A a)
also be passed to B.dosomething2(B b)
?
The answer is simple: no.
B obj_B= new B();
A obj_A= new A();
obj_B.doSomething2(obj_A);
The example above should make it clear why: obj_A
is not an instance of B
, so it can't be passed as a parameter to B.dosomething2(B b)
. Which means that the two methods, although they share the same name do not share the same signature, which in turn means we are overloading the method and not overriding it.
The fact that you happen to call it with something that would fit into both is irrelevant, as selecting which overloaded method to call happens at compile time in Java, based on the variable a2
's type ( A
) and not the runtime class of the object it points to ( B
).
This sort of mistake can easily happen by accident, particularly if you shuffle your methods around and rename them. To avoid accidental overloading when you meant overriding, make sure you always use the @Override
annotation when you intend to override something, that way the compiler will complain.
class B extends A {
@Override //this will compile fine
public void dosomething1(A a){
System.out.println("Inside b dosomething1");
}
@Override //this will fail compilation
public void dosomething2(B b){
System.out.println("Inside b dosomething2");
}
}
This annotation is technically optional but it is so useful that in practice people treat it as if it were mandatory.
It is method Overriding
Why java not calling the method defined in B as on runtime it knows a2 is object of B.
Because dosomething2
in A
and dosomething2
in B
have different signatures.
You are not overriding dosomething2
in B
. In regard to dynamic dispatch, dosomething2
in B
is a new method.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.