Lecture 13-More on Subclasses

Lecture 13-More on Subclasses - CS1110 Lec 13 14 Oct 2010...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: CS1110 Lec. 13 14 Oct 2010 Another classy lecture: Casting about (secs 4.2, 4.3) 1.  the class hierarchy 2.  apparent and real classes 3.  casting between classes 4.  operator instanceof 5.  function equals 6.  abstract methods/classes (section 4.7, labs next week)  Setting: Cmail (Cm) and Umail (Um) accounts. b0 They have commonalities, like netIDs and an "alert" ability, so we make them subclasses of class Acct. Object Acct nid cc1 Acct(String) alert(String) getID() Cm(String) alert(String) newClip(String) Cm the class hierarchy: Reading for next time: Sec. 2.3.8 and chapter 7 on loops. A4 due Saturday; make sure you're using Monday's a4.zip files (see assignments page on the course website for description of updates) Time management tip #42: schedule deadlines on your calendar; also schedule the time it will take to do the work. 1 Acct Cm Um b1 Acct nid uu2 Acct(String) alert(String) getID() Um Um(String) alert(String) popUp(String) 2 But, Cm and Um override Acct method alert(String), due to system differences. Cmail shows a “Web clip”; Umail creates a popup. Why do we keep drawing the overriden alert? [Note: Acct might best be made an abstract class; see last slide and next lab.] c b0 Cm a b0 Acct u b1 b0 Sources of apparent and real types Acct Um nid cc1 Acct(String) alert(String) getID() Cm Cm(String) alert(String) newClip(String) b1 Acct nid uu2 Acct(String) alert(String) getID() Um(String) alert(String) popUp(String) Um Acct a= new Cm("LJL2"); Um u= new Um("DJG17"); Is a= c; legal? b0 is an Acct, but it's also a Cm. The apparent (declared) type of a is Acct, and will always be Acct. This is a syntactic property having to do with compiling. Apparent types come from declarations real types come from assignment The real type of a, the real class of the object whose name is currently in a, is Cm, but could change via assignment: a= u; This is a semantic property having to do with the current value of a. a= u; // apparent type still Acct, real type changes to Um 3 4 Implicit casting up the class hierarchy (good news) u b1 Um 1 b14 2 … … b1 nid uu2 Acct(String) alert(String) getID() Um(String) alert(String) Um Acct More good news: Overriding (still) has the correct behavior b0 Acct nid cc1 Acct(String) alert(String) getID() Cm Cm(String) alert(String) newClip(String) 0 Vector<Acct> v b0 0 Vector<Acct> v b0 1 null 2 b1 [Not drawing Vectors as objects to save space] u has apparent type Um, popUp() but our list v has an apparent type based on Acct. Does this mean we must do an explicit cast to add u to v? v.add( (Acct) u); Nope; luckily, casts up the hierarchy are automatic, allowing this: v.add(u); 5 First, the compiler checks that apparent type Acct has an alert method; if that succeeds, then the bottom-up rule is applied. v.get(0).alert() will call the over-riding, Cmail-specific alert() method. v.get(2).alert() will call the over-riding, Umail-specific alert() method. b1 Acct nid uu Acct(String) 2 alert(String) getID() Um(String) alert(String) popUp(String) Um 6 1 A sensible policy with an embedded “gotcha”: The apparent type can rule out some available methods. b0 Acct nid cc1 Acct(String) alert(String) getID() Cm Cm(String) alert(String) newClip(String) b1 nid uu Acct(String) 2 alert(String) getID() Um(String) alert(String) popUp(String) Um Acct Workaround: check the real type. b0 Acct nid cc1 Acct(String) alert(String) getID() Cm Cm(String) alert(String) newClip(String) b1 a b0 0 Vector<Acct> v b0 1 null 2 b1 Acct The apparent type of v, based on Acct, does not have a newClip method. Therefore, the compiler rules the call v.get(0).newClip(“FLOOD”) illegal, even though in practice, the real type of v.get(0) might mean that newClip(…) would be available. If we insist on calling newClip at all costs, then we need to explicitly downward-cast and/or to declare fresh variables of the right apparent type (Cm, not Acct). To assign correctly to these fresh variables, we need to check the real type: Acct nid uu Acct(String) 2 alert(String) getID() Um 7 if ( a instanceof Cm) { Um(String) Cm newG= (Cm) a; alert(String) … popUp(String) need this downward cast } (can’t just wedge “big” class into small) 8 Example public class Acct { // If Acct is a Cm, apply newClip, o.w, do nothing. public static void tryClip(Acct a, String msg) { if ( ! (a instanceof Cm) ) return; // a is a Cm Cm c= (Cm) a ; // downward cast return c.newClip(msg); } tryClip: 1 a b0 Acct b0 Acct The correct way to write method equals Method equals helps prevent addition of duplicates to lists, etc. Note that method equals should take arbitrary Objects as arguments. public class Acct { … /** = “ob is an Acct with the same values in its fields as this Acct” */ public boolean equals (Object ob) { if (!(ob instanceof Acct)) return false; Acct a= (Acct) ob; // why? b/c Objects don’t // generally have nids return nid.equals(a.nid); } 9 10 cc1 nid Acct(String) alert(String) getID() Cm Cm(String) alert(String) newClip(String) b0 Object equals(Object) Acct cc1 nid Acct(String) alert(String) getID() equals(Object)  Cm Cm(String) alert(String) newClip(String) Acct c b0 Cm Here, (Um) a would lead to a runtime error. Don’t try to cast an object to something that it is not! Apparent type of a: Acct Real type of a: Cm Abstract methods and classes (see lab next week) Make a (superclass) method abstract to force (nonabstract) subclasses to override it (and hence define it): Example: In Acct (note stranded semi-colon!): public abstract void alert(String s) ; means every sub-type of email account must have an alert method --- different for different systems. Make a (super)class abstract if there can only be subclass objects, but you still want default behaviors/info. Example: Nothing is just a generic Animal (it's a Pig, or a Butterfly, or a Person),and all live somewhere; but all Animals breathe oxygen. So, can't create an "Animal": public abstract class Animal() { public boolean breathesOxygen() {return true;} public abstract String habitat() ; } 11 2 ...
View Full Document

This note was uploaded on 11/27/2010 for the course CS 9339 at Cornell.

Ask a homework question - tutors are online