Ana Perez wrote:
but I thought the selection of method to be executed depends upon the actual object class and not the reference, no?
To be executed yes, but to be called, no.
You can call only methods that exist (are declared) in the class of reference variable. But if method is polymorphic, it will be executed based on run-time object (if it is child, then child's method)
If you have parent reference, and want to call child specific method, you have to explicitly cast it, and then call child specific method. This will make code compile, but JVM can still throw exception at runtime if run-time object is not child but parent (or some other exception).
So, when talking about doStruff() in your example, you can call it if you cast a(parent reference variable) to AA (child class)
This will make it compile, but you will get ClassCastException if that variable is not null (or NPE if it is)
Ana Perez wrote:
if I create an object C c = new C(), is it possible to access A's m1() with ((A)c).m1()?
This is same as I already said. Execution of polymorphic methods will be decided at runtime. So, compiler will see that you have m1() method in A class, he is satisfied, but at run-time JVM will see that real object is actually C, and m1() method from C will be called. That is overriding, you don't have parent's methods available. If they were static, they would be available to child classes also, and it would be hiding, not overriding
Basically, whether it is overriding, hiding or overloading, method must exist in reference variable class (either declared or by inheritance), but with overriding, method execution will be determined at run-time based on run-time object (in other cases it will be determined by reference variable, because those methods are not overridden - there is only one copy if that makes sense)
With casting there are 2 things that will cause compile-time error:
1. if there is no IS-A relationship between reference variable type(or type you're instantiating) and type you are trying to cast to
2. if reference variable is not supertype of the type you are trying to cast to
Additionally, there is one thing that will cause ClassCastException
3. if run-time object is not the same or subclass of reference type
Previous code will compile fine, but it will throw CCE at run-time. Your run-time object is Object, compiler was satisfied when you did explicit casting to Integer, but it had no idea what is real run-time object, so JVM throws ClassCastException
Hope this helps a bit