JAVA Object Oriented Programming Objectives • Be able to implement inheritance using extends, super, and abstract • Be able to describe differences between a concrete and abstract class. • Be able to recognize polymorphic behavior 3 You can get stuck at the object-based level because you can quickly get there and you get a lot of benefit without much mental effort. It’s also easy to feel like you’re creating data types – you make classes and objects, you send messages to those objects, and everything is nice and neat. But don’t be fooled. If you stop here, you’re missing out on the greatest part of the language, which is the jump to true object-oriented programming. You can do this only with virtual [abstract] functions. - Bruce Eckel, Thinking in C++, 4 Example: Analysis • We want to make a payroll program that lists each employee, some information about them, and their pay. ... Employee e = new Employee(0, ”Bashful", "customer representative”, 10.0, 40.0); System.out.println(e); System.out.println(e.computePay()); ... OUTPUT: 0 Bashful Role: customer representative Payrate: 10.0 Hours Worked: 40.0 Pay: $400.0 Employee +myId +myName +myRole +myPayrate +myHours +toString() +computePay() 5 Adding More Employee Types • Our initial iteration’s design assumes that all employees are paid in exactly the same way • If we want a different kind of employee, we need to create an entirely new type for it • Bashful was an hourly employee, what about a salaried employee? • What would be the same? • ID, Name, Role • What would be different? • No mention of hours, salary instead of payRate 6 Modeling Objects • Object-Oriented programming models objects and the relationships between them. • Examples: • figures, squares, rectangles, polygons, doodles; • people, students, teachers, staff members, you; • animals, birds, penguins, wings, ; • naval vessels, submarines, carriers, fighter jets. image from http://www.linux.org/info/penguin.html 7 Modeling and Implementing Relationships We have seen two inter-object relationships: • “is a” – instantiation • implemented using constructor methods (for reference objects); • “has a” – aggregation • implemented using instance data references; • specifies container-contained relationships between classes. • The container references the contained. Container +referenceToContained Contained 8 Modeling and Implementing Relationships • Inheritance adds another kind of relationship: • implemented using extends clauses; 9 Class Inheritance • Inheritance specifies one-directional, parent-child relationships. • “is a kind of” – implemented using extends clause • The child inherits the parent’s: • data • methods • Each child can polymorphically “specialize” itself by overriding or adding data or methods. Parent +parent's attributes +parent's operations() Child +parent's attributes +child's attributes +parent's operations() +child's operations() 10 Carl Linneaus (1707-1778) Taxonomy • Systema Naturae, 1758 • 7 levels: • Kingdom • Phylum • Class • Order • Family • Genus • Species images from www.linnean.org & www.kheper.auz.com 11 Example: Java’s Classes • All Java classes fit into one hierarchy. ● All classes inherit from the root class: java.lang.Object • You can find the full Java hierarchy here: http://java.sun.com/javase/6/docs/api/overview-tree.html 12 Example: Design of Employees Employee +myId +myName +myRole +toString() HourlyEmployee SalariedEmployee +myPayrate +myHours +mySalary +computePay() +computePay() 13 Implementing Inheritance • A child class specifies inheritance from a parent class using the extends clause. • Java provides three modifiers specifying access for class variables and methods: • private • protected • public • It can be safer to declare attributes as private and provide protected accessor and mutator methods. 14 Super-Class Constructors • super is a reference to the parent. • A child can invoke its parent’s constructor. super(parentConstructorArguments) • A call to the parent’s constructor: • must be the first statement in the constructor; • is added automatically if you don’t add it. • A child can invoke an overridden method: super.parentMethod(arguments) public class Employee { private int myId; private String myName, myRole; public Employee() { myId = 0; myName = myRole = ""; } public Employee(int id, String name, String role) { myId = id; myName = name; myRole = role; } //accessors and mutators omitted for space @Override public String toString() { return myId + " " + myName + "\n\tRole: " + myRole; } } public class HourlyEmployee extends Employee { private static final double WORK_WEEK = 40.0, OVERTIME_RATE = 1.5; private double myPayrate, myHours; public HourlyEmployee() { myPayrate = myHours = 0.0; } public HourlyEmployee(int id, String name, String role, double payrate, double hours) { super(id, name, role); myPayrate = payrate; myHours = hours; } //accessor and mutators omitted for space, compute pay on comparison slide @Override public String toString() { return super.toString() + "\n\tPayrate: " + myPayrate + "\n\tHours worked: " + myHours; } } 17 Example: Design of Employees Employee +myId +myName +myRole +toString() HourlyEmployee SalariedEmployee +myPayrate +myHours +mySalary +computePay() +computePay() public class SalariedEmployee extends Employee { private double mySalary; public SalariedEmployee() { mySalary = 0.0; } public SalariedEmployee(int id, String name, String role, double salary) { super(id, name, role); mySalary = salary; } //accessors, mutators omitted for space, computePay() on following @Override public String toString() { return super.toString() + "\n\tAnnual Salary: " + mySalary; } } Salaried Hourly Comparison of computePay() //Compute pay for hourly employee @Override public double computePay() { if (myHours <= WORK_WEEK) { return myPayrate * myHours; } else { return (myPayrate * WORK_WEEK) + ((myPayrate * OVERTIME_RATE) * (myHours - WORK_WEEK)); } } //Compute pay for salaried employee @Override public double computePay() { return mySalary; } public class PayrollConsole { public static void main(String[] args) { // 1. Employee only Employee e = new Employee(0, ”Bashful", "customer representative"); System.out.println(e); // 2. HourlyEmployee HourlyEmployee he = new HourlyEmployee(); he.setPayrate(10.0); he.setHours(50.0); System.out.println(he.computePay()); he.setId(1); he.setName("Sneezy"); he.setRole("intern"); System.out.println(he); // 3. SalariedEmployee SalariedEmployee se = new SalariedEmployee(); se.setId(2); se.setName("Doc"); se.setRole("physician"); se.setSalary(100000.0); System.out.println(se); System.out.println(se.computePay()); }} Fruit Example Fruit Apple Orange VALID OR INVALID?? Fruit fruit = new Gala(); Orange orange = new Orange(); Gala Fuji Orange p = new Apple(); Gala p = new Apple(); Apple p = new Fuji(); Examples public class Test { public static void main(String[] args) { B b = new B(); } } class A { public A(){ System.out.println("A's constructor invoked"); } } class B extends A{ } Examples public class Test { public static void main(String[] args) { B b = new B(); } } class A { public A(int x){ System.out.println("A's constructor invoked"); } } class B extends A{ public B (){ System.out.println(“B’s constructor invoked”); } } Examples class Test { public static void main(String[] args) { A a = new B(); System.out.println(a.doThis()); } } class A { public A(){ System.out.println("A's constructor invoked"); } public String doThis(){ return “A’s doThis()”; } } class B extends A{ public B (){ System.out.println(“B’s constructor invoked”); } public String doThis(){ return “B’s doThis()”; } } Back to our goal We want to be able to print out payroll information: ArrayList<Employee> employees = new ArrayList<Employee>(); employees.add(new HourlyEmployee(1, "Sneezy", "intern", 10.0, 40.0)); employees.add(new SalariedEmployee(2, "Doc", "physician", 100000.0)); employees.add(new SalariedEmployee(3, ”Snow White", ”CEO", 175000.0)); employees.add(new SalariedEmployee(4, "Dopey", "trainer", 65000)); employees.add(new HourlyEmployee(5, "Sleepy", "trainee", 15.00, 40.00)); for (int i = 0; i < employees.size(); i++) { System.out.println(employees.get(i)); System.out.println("\tPay: $" + employees.get(i).computePay()); } Problem: There is no computePay() for a generic Employee! 26 Abstract Classes • Classes can be abstract or concrete. visibility abstract class className { classDefinition } • Like concrete classes, abstract classes: • Can have sub-classes; • Can implement data and methods. • Unlike concrete classes, abstract classes: • Cannot be instantiated. 27 Abstract Methods • As with classes, methods can also be declared as abstract or concrete. visibility abstract type methodName(params); • Abstract classes do not provide definitions for their abstract methods. • Classes that contain abstract methods must be declared as abstract. 28 Implementing Inheritance • A child class specifies inheritance from a parent class using the extends clause. • Concrete sub-classes must define the abstract methods that they inherit. Parent +aMethod() Child1 +aMethod() abstract class Parent { public abstract void aMethod(); } class Child1 extends Parent { public void aMethod() { // define method here... } } 29 Abstract Class public abstract class Employee { //private instance variables public Employee(int id, String name, String role) { myId = id; myName = name; myRole = role; } public abstract void computePay(); @Override public String toString() { return myId + " " + myName + "\n\tRole: " + myRole; } } 30 Overriding Methods • When an object to asked to execute a method, Java searches up the inheritance hierarchy for a matching method definition. • Thus, a sub-class that defines its own version of a method overrides any definitions of the methods that it inherits. • A concrete sub-class must implement the abstract methods it inherits using a method with an identical signature. 31 public class HourlyEmployee extends Employee { private static final double WORK_WEEK = 40.0, OVERTIME_RATE = 1.5; private double myPayrate, myHours; public HourlyEmployee(int id, String name, String role, double payrate, double hours) { super(id, name, role); myPayrate = payrate; myHours = hours; } @Override public double computePay() { if (myHours <= WORK_WEEK) { return myPayrate * myHours; } else { return (myPayrate * WORK_WEEK) + ((myPayrate * OVERTIME_RATE) * (myHours - WORK_WEEK)); } } @Override public String toString() { return super.toString() + "\n\tPayrate: " + myPayrate + "\n\tHours worked: " + myHours; }} 32 Polymorphism Parent • Polymorphism allows different concrete sub-classes to provide potentially different definitions for a given method inherited from their shared parent. • Java chooses the appropriate method definition based upon which child the object instantiates at either: • Compile time (static binding); • Run time (dynamic binding). +aMethod() Child1 Child2 +aMethod() +aMethod() 33 Example Parent +aMethod() List<Parent> myObjects = new ArrayList<Parent>(); Child1 Child2 +aMethod() +aMethod() myObjects.add(new Child1(arguments)); myObjects.add(new Child2(arguments)); // add more children of either type... for (int i = 0; i < myObjects.size(); i++) { myObjects.get(i).aMethod(arguments); } Now with abstract Employee class ArrayList<Employee> employees = new ArrayList<Employee>(); employees.add(new HourlyEmployee(1, "Sneezy", "intern", 10.0, 40.0)); employees.add(new SalariedEmployee(2, "Doc", "physician", 100000.0)); employees.add(new SalariedEmployee(3, ”Snow White", ”CEO", 175000.0)); employees.add(new SalariedEmployee(4, "Dopey", "trainer", 65000)); employees.add(new HourlyEmployee(5, "Sleepy", "trainee", 15.00, 40.00)); for (int i = 0; i < employees.size(); i++) { System.out.println(employees.get(i)); System.out.println("\tPay: $" + employees.get(i).computePay()); } This now works because Java knows that every employee will have a computePay method. 35 Fredrick P. Brooks (1931- ) The Mythical Man-Month What’s the Big Idea Joys of programming Woes of programming We enjoy designing things because we are created in the image of God. The “mindless” details can be excessively tedious. The computer is a powerful and rewarding tool to use. Products become obsolete too quickly. As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God's delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake. - F. P. Brooks, Jr. The Mythical Man-Month, 1975 images from: http://www.amazon.com/