简体   繁体   中英

Java superclass calls subclass method

I have these classes:

class A {
  public void f() { System.out.println("f() in A"); }
  public void g() { System.out.println("g() in A"); f(); }
}

class B extends A {
  public void f() { System.out.println("f() in B"); }
}

Why does

B b = new B();
A a = b;
a.g();

print out this

g() in A
f() in B

and not

g() in A
f() in A

Is there something I am missing?

This is because Java uses dynamic dispatch by default (and forcibly) on methods of classes.

This feature makes sure that, when a method is called, the most specialized version of it it is chosen to be executed. In your case, since B extends A , it means that public void f() implementation of B is more specialized than the one of A . So although A a is statically of type A , it's dynamically of type B and that method is chosen.

是的,即使变量“a”是A类型,它所持有的对象引用也是B类型,因此B中的f()是所谓的。

https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html

This is called polymorphism. It lets us do things like hold a list of type Animal, but when we put a cat in it, and do animal.performcall() it will print a meow. This is the example my teacher gave me many years ago, anyway :)

The reference variable type of an object determines which methods are accessible.

The class of an object determines which methods exist. These methods that exist but are not accessible can be accessed through casting.

ie: ((B) a).g(); Will allow you to access the B version of G. This only works because underneath a is a B .

Now you got idea about polymorphism and overriding.

Since you did not get your expected output, I would suggest a way to get your expected output through method shadowing or hiding

If you re-define base class non-static & non-private method in derived class, it's called overriding .

In this example, A holds the instance of B and hence f() has been invoked from B instead of A.

If you re-define base class static method/variable is derived class, it's called hiding or shadowing .

In above example, just add static modified for g() method and you will get required output. Now g() method

class A {
  public static int i=10;
  public static void f() { 
    System.out.println("f() in A:i="+i); 
  }
  public void g() { System.out.println("g() in A"); f(); }
}

class B extends A {
  public static int i=20;
  public static void f() { 
      System.out.println("f() in B:i"+i); 
  }
}
public class Test2 {
    public static void main(String args[]){
        B b = new B();
        A a = b;
        a.g();
    }
}

output:

g() in A
f() in A:i=10

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