Improving structure with inheritance (Chapters 8 and 9) Main concepts to be covered • • • • Inheritance Subtyping Substitution Polymorphic variables Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2 The DoME example "Database of Multimedia Entertainment" • stores details about CDs and DVDs – CD: title, artist, # tracks, playing time, gotit, comment – DVD: title, director, playing time, got-it, comment • allows (later) to search for information or print lists Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3 DoME objects Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 4 DoME classes top half shows fields bottom half shows methods Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5 DoME object model Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 6 Class diagram Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 7 CD source code [ public class CD { private String title; private String artist; private String comment; public CD (String theTitle, String theArtist) { title = theTitle; artist = theArtist; comment = "<no comment>"; } public void setComment (String newComment) { ... } ] incomplete (comments!) public String getComment () { ... } public void print () { ... } ... other methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 8 DVD source code [ public class DVD { private String title; private String director; private String comment; public DVD (String theTitle, String theDirector) { title = theTitle; director = theDirector; comment = "<no comment>"; } public void setComment (String newComment) { ... } ] incomplete (comments!) public String getComment () { ... } public void print () { ... } ... other methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 9 Database source code class Database { private ArrayList<CD> cds; private ArrayList<DVD> dvds; ... addCD, addDVD public void list () { for(CD cd : cds) { cd.print (); System.out.println (); } for(DVD dvd : dvds) { dvd.print (); System.out.println (); } // empty line between items // empty line between items } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 10 Critique of DoME • code duplication – CD and DVD classes very similar (large part are identical) – makes maintenance difficult/more work – introduces danger of bugs through incorrect maintenance • code duplication also in Database class Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 11 Using inheritance Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 12 Using inheritance • define one superclass : Item • define subclasses for Video and CD • the superclass defines common attributes • the subclasses inherit the superclass attributes • the subclasses add own attributes Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 13 Inheritance hierarchies Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 14 Inheritance in Java public class Item { ... } public class CD extends Item { ... } no change here change here public class DVD extends Item { ... } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 15 Superclass public class Item { private private private private ... String title; int playingTime; boolean gotIt; String comment; constructors and methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 16 Subclasses public class CD extends Item { private String artist; private int numberOfTracks; ... constructors and methods } public class DVD extends Item { private String director; ... constructors and methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 17 Inheritance and constructors public class Item { private String title; private int playingTime; private boolean gotIt; private String comment; /** * Initialise the fields of the item. */ public Item (String theTitle, int time) { title = theTitle; playingTime = time; gotIt = false; comment = ""; } ... methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 18 Inheritance and constructors public class CD extends Item { private String artist; private int numberOfTracks; /** * Constructor for objects of class CD */ public CD (String theTitle, String theArtist, int tracks, int time) { super (theTitle, time); artist = theArtist; numberOfTracks = tracks; } ... methods } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 19 Superclass constructor call • Subclass constructors must always contain a 'super' call. • If none is written, the compiler inserts one (without parameters) – this works only, if the superclass has a constructor without parameters • The 'super' call must be the first statement in the subclass constructor. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 20 Adding more item types Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 21 Deeper hierarchies Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 22 Review (so far) Inheritance (so far) helps with: • Avoiding code duplication • Code reuse • Easier maintenance • Extendibility Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 23 public class Database { private ArrayList<Item> items; /** * Construct an empty Database. */ public Database () { items = new ArrayList<Item> (); } /** * Add an item to the database. */ public void addItem (Item theItem) { items.add (theItem); } ... New Database source code avoids code duplication in client! list } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 24 New Database source code /** * Print a list of all currently stored CDs and * DVDs to the text terminal. */ public void list() { for(Item item : items) { item.print(); // Print an empty line between items System.out.println(); } } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 25 Subtyping First, we had: public void addCD (CD theCD) public void addVideo (DVD theDVD) Now, we have: public void addItem (Item theItem) We call this method with: DVD myDVD = new DVD (...); database.addItem (myDVD); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 26 Subclasses and subtyping • Classes define types. • Subclasses define subtypes. • Objects of subclasses can be used where objects of supertypes are required. (This is called substitution.) Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 27 Subtyping and assignment subclass objects may be assigned to superclass variables Vehicle v1 = new Vehicle(); Vehicle v2 = new Car(); Vehicle v3 = new Bicycle(); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 28 Subtyping and parameter passing public class Database { public void addItem(Item theItem) { ... } } DVD dvd = new DVD(...); CD cd = new CD(...); subclass objects may be passed to superclass parameters database.addItem(dvd); database.addItem(cd); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 29 Object diagram Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 30 Class diagram Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 31 Polymorphic variables • Object variables in Java are polymorphic. (They can hold objects of more than one type.) • They can hold objects of the declared type, or of subtypes of the declared type. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 32 Casting • Can assign subtype to supertype. • Cannot assign supertype to subtype! Vehicle v; Car c = new Car(); v = c; // correct; c = v; // will not compile • Casting fixes this: c = (Car) v; // compiles OK (run-time error if v is not a Car!) Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 33 Casting • An object type in parentheses. • Used to overcome 'type loss'. • The object is not changed in any way. • A run-time check is made to ensure the object really is of that type: – ClassCastException if it isn't! • Use it sparingly. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 34 The Object class All classes inherit from Object. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 35 Polymorphic collections • All collections are polymorphic. • We can have collections of <Object>. public void add (Object element) public Object get (int index) Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 36 Collections and primitive types • All objects can be entered into such collections ... • ... because such collections accept elements of type Object... • ... and all classes are subtypes of Object. • Great! But what about simple types? Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 37 Wrapper classes • Primitive types (int, char, etc) are not objects. To collect them, they must be wrapped into an object! • Wrapper classes exist for all simple types: simple type int float char ... wrapper class Integer Float Character ... Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 38 Wrapper classes int i = 18; Integer iwrap = new Integer(i); ... int value = iwrap.intValue(); wrap the value unwrap it In practice, autoboxing and unboxing mean we don't often have to do this. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 39 Autoboxing and unboxing private ArrayList<Integer> markList; … public void storeMark (int mark) { markList.add (mark); autoboxing } int firstMark = markList.remove (0); unboxing Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 40 Autoboxing and unboxing private ArrayList<Integer> markList; … public void storeMark (int mark) { markList.add (new Integer (mark)); } so we don’t have to write this int firstMark = markList.remove(0).intValue(); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 41 Review so far ... • Inheritance allows the definition of classes as extensions of other classes. • Inheritance – – – – avoids code duplication allows code reuse simplifies the code simplifies maintenance and extending • Variables can hold subtype objects. • Subtypes can be used wherever supertype objects are expected (substitution). Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 42 More about inheritance Exploring polymorphism (Chapter 9) Main concepts to be covered • • • • • method polymorphism static and dynamic type overriding dynamic method lookup protected access Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 44 The inheritance hierarchy Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 45 Conflicting output What we want CD: A Swingin' Affair (64 mins)* Frank Sinatra tracks: 16 my favourite Sinatra album DVD: O Brother, Where Art Thou? (106 mins) Joel & Ethan Coen The Coen brothers’ best movie! What we have title: A Swingin' Affair (64 mins)* my favourite Sinatra album title: O Brother, Where Art Thou? (106 mins) The Coen brothers’ best movie! Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 46 The problem • The print method in Item only prints the common fields. • Inheritance is a one-way street: – A subclass inherits the superclass fields. – The superclass knows nothing about its subclass’s fields. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 47 Attempting to solve the problem • Place print where it has access to the information it needs. • Each subclass has its own version. • But Item’s fields are private. • Database cannot find a print method in Item. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 48 Static type and dynamic type • A more complex type hierarchy needs further concepts to describe it. • Some new terminology: – static type – dynamic type – method dispatch/lookup Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 49 Static and dynamic type What is the type of c1? What is the type of v1? Car c1 = new Car(); Vehicle v1 = new Car(); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 50 Static and dynamic type • The declared type of a variable is its static type. • The type of the object a variable refers to is its dynamic type. • The compiler’s job is to check for static-type violations. for(Item item : items) { item.print(); // Compile-time error. } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 51 Overriding: the solution print method in both superand subclasses. Satisfies both static and dynamic type checking. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 52 Overriding • Superclass and subclass define methods with the same signature. • Each has access to the fields of its class. • Superclass satisfies static type check. • Subclass method is called at runtime – it overrides the superclass version. • What becomes of the superclass version? Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 53 Method lookup No inheritance or polymorphism. The obvious method is selected. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 54 Method lookup Inheritance but no overriding. The inheritance hierarchy is ascended, searching for a match. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 55 Method lookup Polymorphism and overriding. The ‘first’ version found is used. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 56 Method lookup summary The variable is accessed. The object stored in the variable is found. The class of the object is found. The class is searched for a method match. If no match is found, the superclass is searched. • This is repeated until a match is found, or the class hierarchy is exhausted. • Overriding methods take precedence. • • • • • Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 57 Super call in methods • Overridden methods are hidden ... • ... but we often still want to be able to call them. • An overridden method can be called from the method that overrides it. – super.print (...) – Compare with the use of super in constructors. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 58 Calling an overridden method public class CD extends Item { ... public void print () { super.print (); System.out.println (" " + artist); System.out.println (" tracks: " + numberOfTracks); } ... } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 59 Method polymorphism • We have been discussing polymorphic method dispatch. • A polymorphic variable can store objects of varying types. • Method calls are polymorphic. – The actual method called depends on the dynamic object type. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 60 The Object class’s methods • Methods in Object are inherited by all classes. • Any of these may be overridden. • The toString method (of Object) is commonly overridden: – public String toString () – Returns a string representation of the object. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 61 Overriding toString public class Item { ... public String toString () { String line1 = title + " (" + playingTime + " mins)"); if (gotIt) { return line1 + "*\n" + " " + comment + "\n"); } else { return line1 + "\n" + " " + comment + "\n"); } } ... } Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 62 Overriding toString • Explicit print methods can often be omitted from a class: System.out.println (item.toString()); • Calls to println with just an object automatically result in toString being called: System.out.println (item); Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 63 Protected access • Private access in the superclass may be too restrictive for a subclass. • The closer inheritance relationship is supported by protected access: protected things (fields, constructors, methods, etc.) may be used by sub-classes. • Protected access is more restricted than public access. • We still recommend keeping fields private. – Define protected accessors and mutators for sub-classes to use. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 64 Access levels Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 65 Review • The declared type of a variable is its static type: – Compilers check static types. • The type of an object is its dynamic type: – Dynamic types are used at runtime. • Methods may be overridden in a subclass. • Method lookup starts with the dynamic type. • Protected access reflects inheritance. Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 66