Next class is last class: review and teacher evaluations
Reading Guide for
Chap. 9
1. Read Chap. 9 to middle of pg. 566. We are substituting the Vehicle hierarchy for the Stock hierarchy that follows here.
2. Read pp. 572-582 Object Class and basic polymorphism discussion
3. Read Sec. 9.5 Interfaces
4. On pg. 611, read the definition of abstract class. Use our Vehicle hierarchy (last version) for an example of an abstract class. Also the Ticket example of hw5.
We looked again at the class diagrams of the Vehicle-Automobile-Truck example, shown in the previous class notes.
There we see two methods handled completely in the superclass, Vehicle, and another, getLicenseClass(), specified in the superclass but implemented differently in the two subclasses, so that all Automobiles and most Trucks (light and medium duty trucks) return “C” for getLicenseClass(), but heavy-duty Trucks (truck class 7 or 8) return “B”.
We saw two different ways to do this, and in both cases involve code in subclass(es) overriding the getLicenseClass() method specified in the superclass.
This setup with Automobile-specific code and Truck-specific code for the same method specified in the superclass is a setup that can show polymorphism, defined on pg. 578.
Polymorphism is shown by code that behaves differently depending on the actual type of the object being used.
To understand what “actual type” means here, consider:
Vehicle v = new Truck(“Freightliner”, 8, “1G123”);
Here we have a Vehicle reference pointing to a Truck object, so there are two types in play, closely related to each other of course.
In this case we call the Vehicle type the static type, and the Truck type the “runtime type” or “actual type”. The actual type is always a subtype of the static type, or the same type.
Since getLicenseClass() is defined for Vehicle, we know we can do “v.getLicenseClass()”.
When this executes it executes “in” the actual type object, so it executes the code for getLicenseClass() in Truck.
Thus v.getLicenseClass() returns “B”, since this object represents a heavy-duty truck.
But if we go on and put
v = new Automobile(…);
v.getLicenseClass() now executes code in Automobile, and returns “C”.
So “v.getLicenseClass()” is code displaying polymorphism: It behaves differently based on v being Truck or Automobile.
We have used polymorphism before, when we looped through arrays or ArrayLists of Shapes calling area() and perimeter(), because area has different formulas for Circles and Rectangles, etc. Shape is an interface, so we see that polymorphism can arise with inheritance and also with use of interfaces.
Now let’s return to the Employee class hierarchy as written in the textbook, to make sure this example is clear, and give in a class diagram.
Employee Class Hierarchy in Chap. 9 : handout, now filled in:
(not the same as the online code) With added return values in parentheses
Note that a LegalSecretary IS-A Secretary IS-A Employee, and a Lawyer IS-A Employee
LegalSecretary lucy = new LegalSecretary(); // reference and
object both of type LegalSecretary
lucy.getHours() returns __40____
lucy.getSalary() returns __45000____
lucy.takeDictation() works? Y/N Y, because a LegalSecretary
IS-A Secretary
Employee lucy1 = lucy; // reference of type Employee, object of
type LegalSecretary: so we can
call any Employee method using lucy1, and for these, the LegalSecretary
code will execute since the object is of type LegalSecretary
lucy1.getHours() returns ___40___
lucy1.getSalary() returns __45000____ method is OK since in Employee API, object’s getSalary() executes
lucy1.takeDictation() works? Y/N N, because takeDictation is not in the Employee API
Employee
leia = new Lawyer(); // ref of type Employee, object of type
Lawyer
leia.getSalary()
returns ___40000___
leia.getVacationDays() returns __15__ method is OK since in Employee API,
object’s getVacationDays executes
We added Marketer to the above picture, as done in hw5.
Finally, we discuss how inheritance and interfaces relate to each other.
Both inheritance and interfaces allow us to bridge across classes to take advantage of common properties of different objects.
Both inheritance and interfaces define subtypes and supertypes and IS-A relationships between them.
In fact, an interface is very much like a superclass with all abstract methods and no constructor (and no fields, to be more exact). We noted how an abstract method is set up much like an interface method: just the method header, no code. So there is a near continuum between inheritance and interfaces.
We have seen that inheritance allows code reuse. Vehicle.java has one copy of code for getMake() and getVIN(), replacing duplicate code in the original Automobile.java and Truck.java.
The added abstract method getLicenseClass() goes against this same-code pattern. That shows the flexibility of this whole system: it can reuse code where possible and accommodate variable code where needed.
If all methods end up abstract, you might as well use an interface. Interfaces have the added advantage that a class can implement multiple interfaces, but may only extend a single class, so inheritance has to be chosen to be the “main thing” about the classes.