简体   繁体   中英

Is it method overriding or overloading?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM