简体   繁体   中英

weird behavior of Inheritance and polymorphism [Java]

Suppose I have the following classes in Java:

class B {

  public void foo(B obj) {
      System.out.print("B1 ");
  }

  public void foo(C obj) {
      System.out.print("B2 ");
  }
}

public class C extends B {

  public void foo(B obj) {
      System.out.print("C1 ");
  }

  public void foo(C obj) {
      System.out.print("C2 ");
  }

  public static void main(String[] args) {
      B c = new C();
      B b = new B();

      b.foo(c); 
      c.foo(b); 
      c.foo(c); 

  }
}

Why am I getting a result of:

B1

C1

C1

I don't understand what happened exactly specially for the part:

c.foo(b); // prints C1

c.foo(c); // prints C1

The b and c variables are both of TYPE B. This is because you declared them as:

**B** c = new C();
**B** b = new B();

When you pass c.foo(b) or c.foo(c) since they are both of class B types they will print "C1"

You can actually check the type of the variables by running the code:

 if (c instanceof B) {
        System.out.println("c is of type B"); //this will print
    }
    else {
        System.out.println("c is of type B");
    }


 if (b instanceof B) {
        System.out.println("b is of type B"); //this will print
    }
    else {
        System.out.println("b is of type B");
    }

The Java virtual machine (JVM) calls the appropriate method for the object that is referred to in each variable. It does not call the method that is defined by the variable's type. This is runtime Polymorphism.

B c = new C();  
c.foo(b); 
c.foo(c); 

in above case, though the variable type is of B but the object it is referring to is of Object Type C. Hence C class method gets invoked.

Now why it prints C1 because of Java Lang Specifications as below:

When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4).

This is call run time polymorphism.

When you make super class reference and assign a sub class object and calling method it will call to override method in sub class not the super class original method.

reference variable c is in type B that is why it prints C1

c.foo(c); // prints C1

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