Polymorphism only applies to overridden methods. Each objects overridden toString() executes, but the instance variable that is referenced is always the one defined in the Fruit class. Polymorphism has absolutely nothing to do with instance variables, therefore the reference variable type decides which instance variable value is printed.
polymorphism is built off the relationship between classes, or inheritance. when you are using a class attribute, name in this case the subclass has to pass its name attribute to the super class, otherwise the class attribute will always be that of the class.
"If the facts don't fit the theory, get new facts" --Albert Einstein
1) Variables are never overridden.
2) Variables are binded during compile time
Based on above, 'o' is casted to Fruit and no matter whether 'o' refers to Fruit or Apple or even another subclass of Fruit object at Runtime. Decision to access which variable was taken at compile time and at that time we ONLY know that that variable is of type Fruit because of the cast.
That's why this always prints 'Fruit'
System.out.println(( (Fruit) o).name);
Where there are more wonders there is less knowledge