this is the nature and basic concept of casting and
polymorphism.
basically because aref is a refrence to class A it always will check first in class a for the method and variables. (even if it actually points to object of class B).
if it finds a method there like print() then IF there is an overriden version of print in class B it will perform the print of class B (if there wasnt one he would have performed the one in class A).
however, if u define new function OR variables in the class that inherit from A (like doThis() for example) then the compiler gets stuck.remember that the compiler thinks aref refers to class Aso he doesnt find any doThis() there.
in order to tell the compiler that he actually points to class B in this case we need to do casting like this:
((B)aref).doThis();
now we tell the compiler to look at aref as a refrence to class B in this sentence so he will perform the action!