A. Introduction
Consider the Shape class and its three subclasses below. There are three methods in the superclass: area(), perimeter(), and toStr(). Rectangle class overrides only toStr(); Triangle class overrides all three methods, and Circle class overrides only area() and perimeter() besides providing new methods of toString(), roll() and equals(). Notice toString() does not override toStr() since they have different names.




B. Dynamic Binding:
Now review the Main class which creates an array of three different shapes:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Shape[] three = new Shape[3];
Scanner in = new Scanner(System.in);
for(int i=0;i<three.length;i++){
System.out.println("What shape do you have?(1-circle, 3-Triangle, 4-rectangle)");
int choice = in.nextInt();
in.nextLine();
System.out.println(" choice: " + choice);
if(choice==1){
System.out.println("radius and center?");
double r = in.nextDouble();
double x = in.nextDouble();
double y = in.nextDouble();
in.nextLine();
Point p = new Point(x, y) ;
three[i] = new Circle(p, r);
((Circle)three[i]).roll(); // type casting
}
else if (choice ==3){
System.out.println("three sides of the triangel?");
double a = in.nextDouble();
double b = in.nextDouble();
double c = in.nextDouble();
in.nextLine();
three[i]=new Triangle(a, b, c);
// Is it possible to convert a triangle into a circle? - A runtime type casting exception!
((Circle)three[i]).roll();
}
else if (choice==4){
System.out.println("length and width?");
double l = in.nextDouble();
double w = in.nextDouble();
in.nextLine();
three[i] = new Rectangle(l, w);
}
System.out.println(three[i].toStr()+", area = "+three[i].area()+", perimeter = "+three[i].perimeter());
}
}
}
Notice three[i].toStr(), three[i].area(), and three[i].perimeter() will invoke different versions of toStr(), area(), and perimeter() depends on the ACTUAL object type of three[i].
Parent-child relationship rules #5: the following type rules must be followed for calling polymorphic methods

C. Type Casting
Notice 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.
D. Try this:
Question 1-15 at end of Chapter 3 (page 150), Barron's AP CS A