In Java, all non-static methods are "virtual", meaning that they are based on the runtime type of the underlying object rather than the type of the reference that points to that object. Therefore, it doesn't matter which type you use in the declaration of the object, the behavior will be the same.
What the declaration does affect, is the methods that are visible at compile-time. If SubClass
has a method that SuperClass
does not (let's call it subMethod()
), and you construct your object as
SuperClass s = new SubClass();
Then you will only be able to call methods on it that are available on SuperClass
. That is, attempting to call s.subMethod()
will give you a compile time error. But, as you have discovered, if there methods are present in SuperClass
, but overridden by SubClass
, it will be the overridden method that will be executed.
Static methods, on the other hand, are not virtual. Running the code below
public class StaticTest {
public static void main(String[] args) {
SuperClass s = new SubClass();
s.method(); // bad idea - calling static method via an object reference
}
public static class SuperClass {
public static void method() {
System.out.println("SuperMethod");
}
}
public static class SubClass extends SuperClass {
public static void method() {
System.out.println("SubMethod");
}
}
}
prints out "SuperMethod". You should rarely care, however, that static
methods are non-virtual because you should never call them via an object reference as I have done above. You should call them via the class name:
SuperClass.method();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…