We must remember that those variables are really object references. They are pointing to appropriate objects in the memory. Memory is allocated at runtime. A parent class reference variable can point to child class objects also. At the time of compilation, it is difficult to say the type of object the parent class reference variable is referring. So the compiler won't say anything at the time of compilation. Real type checking is carried out at run time only. If incorrect casting is carried out, a runtime exception is thrown. I think it clears your doubt.