Notice in the previous example, array three is of type Shape, where each element can be of Rectangle, Triangle, or Circle. Assigning a subclass type object to a superclass type variable is upcasting. Upcasting is always successful.
When calling the roll() method, a Shape object has to be explicitly cast into a Circle type since roll() method is only available for a Circle type. Converting a
declared superclass object into a subclass type is downcasting. Depends on the actual type of the object, downcasting may or may not be successful, as indicated when casting a Triangle object to a Circle type in choice 3 above.
If the casting is not feasible, a runtime exception ClassCastException will be thrown.