CS100J. Summary of casting and overriding. February 2003. // An instance of Employee contains person's name, salary, and year hired. public class Employee { private String name; // The person's name private double pay; // The person's yearly pay private int hireDate; // The year hired // Constructor: a person with name n, pay s, and // year d hired public Employee(String n, double s, int d) {name= n; pay= s; hireDate= d;} // = the person's name public String getName() {return name;} // = the person's pay public double getPay() {return pay;} // = the year the person was hired public int getHireDate() {return hireDate;} // = a String containing the data for the person public String toString() {return name + ", " + pay + ", " + hireDate;} // Print employee p only if their total salary is > 5000 public static void printEmployee(Employee e) { if (e.getPay() > 50000) { System.out.println(e); } } } =================================== // An instance of VIP contains a VIP's data public class VIP extends Employee { private double bonus; // The VIP's bonus // Constructor: name n, pay s, year d hired, and bonus b public VIP(String n, double s, int d, double b) {super(n, s, d); bonus= b; } // = a String containing the data for the person public String toString() {return "VIP " + super.toString() + ", " + "+ bonus of " + bonus;} // = pay for this VIP public double getPay() { return super.getPay() + bonus; } // Change the bonus to b public void changeBonus(double b) {bonus= b;} } ================================== // An instance of Salaried contains a salaried person's data public class Salaried extends Employee { // Constructor: instance with name n, pay s, hire date d public Salaried(String n, double s, int d, double b) {super (n, s, d);} // Yield a String containing the data for the person public String toString() {return "Salaried " + super.toString();} } ================================= Use these variables in examples: Employee e1; VIP v1; Salaried s1; Employee e2; VIP v2; Salaried s2; CASTING RULES 0. Rule. You can cast from subclass to superclass automatically or explicitly: e1= new VIP("Gries", 50000, 1999, 40000); e2= (Employee)(new VIP("Lether", 60000, 1992, 40000)); 1. Rule. You can cast from superclass to subclass ONLY if you are positive that the instance is a member of the subclass. You have to use an explicit cast v1= e1; is illegal. Program won't compile v1= (VIP) e1; is legal, and works e2= (Salaried) e1; is legal, but it produces an error at runtime 2. Use binary operation instanceof to tell whether an instance belongs to a class: if (e1 instanceof VIP) v1= (VIP)e1; Use this sparingly. ------------------------------- RULES FOR REFERENCING AN INSTANCE METHOD OR VARIABLE For a variable v defined by C v;, it's APPARENT CLASS is C; it's real class is the class with which the object v was declared. Example: consider Employee e= new VIP(...); The apparent class of e is Employee; it's real class is VIP. 3. Rule. You can refer to an instance method from a class variable v ONLY if that instance method is defined in v's apparent class. e1.toString() is legal. The program will compile e1.changeBonus(50000); is illegal. The program won't compile 4. Rule. Whenever you look for a method or variable in an instance of a class, start at bottom and search upward! Always! This ensures that you always get a overriding instance, if there is one. e1.toString() yields "VIP Gries, 50000, 1999, 40000"; 5. Rule (for this course, and for almost everyone). Don't override instance variables. ------------------------------- WHY DOES IT WORK THIS WAY? Consider this method to print an employee: // Print employee p only if their total salary is > 5000 public static printEmployee(Employee e) { if (e.getPay() > 5000) { System.out.println(e); } } Suppose you write a call Employee.printEmployee(v1); where v1 is a VIP. v1 is cast automatically to Employee and its value is assigned to e. e.getPay() is legal since getPay is available in the apparent class, Employee. But when it is called, we want the VIP's getPay method --to use the Employee's getPay method would make it all useless.