At run time, the JVM knows that your variable s is a "SubClass" and therefore can call the correct (overwritten) method.
The problem you are facing at compile time. The compiler tries to check your program to make sure that you haven't made any mistakes. He has no idea about the types of variables, except for the type you are talking about.
// the Java compiler remembers that there is a variable called 's' and that // it has the type 'SuperClass'. Note that the compiler does not check the // actual type of the instance. It just checks to see if the assignment is // is valid. Since the right side is of type 'SubClass' and the left side // has the type 'SuperClass' which is a parent of 'SubClass' this assignment // is valid for the compiler. But it ONLY remembers that 's' is of type // 'SuperClass' since that is what you told it about 's'. SuperClass s = new SubClass(); // Here the compiler sees 's' and looks up its type. The type of 's' is // 'SuperClass' as remembered earlier. javac will no go and look up the // definition of 'SuperClass' and finds out that 'SuperClass' does not // have a method with the name 'subClass' so you get a compiler error. s.subClass();
The reason the compiler does this is because you said that the compiler is of type SuperClass. Thus, any assignment for anything that extends SuperClass is a valid assignment for 's'. Theoretically, you can assign SuperClass 's'. If the compiler does not perform this check, you can write code that calls methods on objects that may not have these methods, which will lead to a runtime error. Having an error like randomly occurring at runtime is much worse than a compiler just checking all assignments and calls, since you can fix them immediately, and runtime errors are sometimes hard to find and fix.
As others have pointed out, you can tell the compiler that you are actually a βSubClassβ later by saying it:
((SubClass) s).subClass();
With this, you basically tell the compiler: "I know that s is actually a" SubClass ", so please consider it as one for this part." If you are somehow mistaken about this, and although your "really" SuperClass is at run time, you will get a "ClassCastException", which is a run-time error, because the JVM does not know what to do at the moment.
source share