QUESTIONS LAST TIME: - M & p quiz redux; amortized O(1); open-addressing; designing with objects TODAY: - Designing with objects - Extending classes - Quiz return PROJECT 2 STATUS - Under development - Still hoping for spec before the weekend TODAY'S SAMPLE MIDTERM QUESTION IS RATED: Typical 1. The time to find an existing key in a separate-chaining hash table containing 'n' associations, in the worst case, is BEST described by: 2 (a) O(1) (c) O(log n) (e) O(n ) (b) amortized O(1) (d) O(n) (f) something else ONTIME QUIZ 3 RESULTS - MUCH IMPROVEMENT 6 ++---------------------------------------------------------------------+ | Quiz 2 +----+ | | | 5 ++ +--+ +--+ | | | | | | | | | | | | | 4 ++ +--+| |--+ | | | | || | | | | 3 ++ +--+ +--+--+ || | | | | | | | | | | || | | | | | | | | | | || | | | | 2 ++ +--+ |+--+ | | | || | | | | | | | || | | | | || | | | | | | | || | | | | || | | | | 1 ++ +--+--+ | | || | +--+| | | || | | | | | | | | | | || | | || | | || | | | | | | | | | | || | | || | | || | | | | 0 ++--+-------------+------------+------------+------------+-------------+ + + + + + + 0 2 4 6 8 10 x ONTIME QUIZ 3 RESULTS - MUCH IMPROVEMENT 25 ++--------------------------------------------------------------------+ | Quiz 3 +----+ | | | 20 ++ +--+ | | | | | | | | | | | | | 15 ++ | | | | | | | | | | | 10 ++ +--+ | | | | | | | | | | | | | | | | | 5 ++ +--+ | | | | | | | | | | +--+ +--+--+ +--+--+--+| | | | | 0 ++--+------------+------------+-------------+------------+------------+ + + + + + + 0 2 4 6 8 10 x AMORTIZED O(1) ALGORITHMS The double-and-copy trick can be applied in lots of places. For example, hash table resizing. If you can get your algorithms so that (time to insert one key-val pair) is (approximately) O(1), and (time to rehash one key-val pair) is (approximately) O(1), then amortized time to store or get a key-val pair, including rehashing, is also (approximately) O(1). Question: Do you have to *double* when you rehash? On overflow Store Find If size = 2*size; -> O(1) O(1) size = 3*size; -> O(1) O(1) size = 3*size/2; -> O(1) O(1) (if size>1!) size = size+1; -> O(n) O(1) size = size+100000;-> O(n) O(1) -> Not double, necessarily, but most grow in proportion to size.. HASH TABLES - OPEN ADDRESSING - QUADRATIC PROBING Where to put a collided key? - Linear probing: Try slot+1, slot+2, slot+3, slot+4... wrapping around - Quadratic probing: Try slot+1, slot+4, slot+9, slot+16... wrapping around + Leaves lots of nearby slots (e.g., slot+2, slot+3) open for other keys.. - Will we even hit every slot, eventually?? -> Quadratic probing is guaranteed to find an empty slot IF: (1) The table is LESS than half full, AND (2) The size of the table is a PRIME number. - Really such a win? Well, (1) In practice you don't want tables to get anywhere near full anyway, (2) And linear probing is really really bad. - Well, what about other non-really-really bad possibilities? -> DOUBLE HASHING: Let the 'collision increment' depend on the hash too. HASH TABLES - OPEN ADDRESSING - DOUBLE HASHING - UPSHOTS - Make the first probe (0..tablesize-1) and the collision increment both (1..tablesize-1) both depend on the key, but in 'different', 'independent' ways. - Table size must be prime to ensure all slots accessible = (And >1 if the 1+h%(tablesize-1) approach to increment is used.. - Would be nice to have two whole separate hash functions, but often that's hard to come by: index = hash1(key) folded into 0..tablesize-1 incr = hash2(key) folded into 1..tablesize-1 - Well-designed implementations of open addressing with double hashing often *significantly outperform* separate chaining implementations! = Q: Why? All the operations are the same big-Oh's? = A1: In the real world, Big-Oh hides a multitude of sins. = A2: No single reason. But typically including things like: - Cache behavior. Separate chaining jumps all over the place - One integer addition and one comparison is fast compared to memory access HASHMAP VS TREEMAP - HashMap is one of two main Map implementation strategies. => The other is called TreeMap - TreeMap uses a kind of tree to store the associations (we don't have to worry specifically how it does it.) => There are lots of possible tree algorithms for this sort of task. Some names: 'red-black tree', '2-3 tree', 'AVL tree'... - What we really need to know is this comparison chart between Hash and Tree: For n entries in the Map or Set: HashMap, HashSet TreeMap, TreeSet storage method hashtable red-black tree space used O(n) O(n) put speed approx O(1) O(lg n) contains speed approx O(1) O(lg n) key methods hashCode, equals compareTo, equals iteration order arbitrary sorted Rule of thumb: Use a Tree only if you need them sorted, otherwise use a Hash DESIGNING WITH OBJECTS - In general, make a class to represent each 'natural kind' of thing that occurs in a programming problem. - (In addition, extra classes are often used to implement 'design patterns' -- stereotypical ways of accomplishing various tasks.) - Beginners to object-oriented programming tend to make two mistakes: = Not making enough classes (E.g., everything in one class) = Making too many classes (E.g., a separate class for every integer) - For now, assume each class goes into its own .java file, with the file named identically to the class name. - Classes stored in the same directory can generally access each other - Guess likely classes: = in a poker-playing program = in an online music store = in a dorm-room assignment system = in a spreadsheet = in a video-player program = in a artificial ecology simulation program EXTENDING CLASSES - (AKA 'inheritance') EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong - AKA 'subclassing'. 'A subclass extends a superclass.' EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong - AKA 'subclassing'. 'A subclass extends a superclass.' - Why do the Java folk talk like 'extension'? Why not 'inheritance'? EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong - AKA 'subclassing'. 'A subclass extends a superclass.' - Why do the Java folk talk like 'extension'? Why not 'inheritance'? - The class contract EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong - AKA 'subclassing'. 'A subclass extends a superclass.' - Why do the Java folk talk like 'extension'? Why not 'inheritance'? - The class contract = Both the externally accessible methods/fields, AND their descriptions = Contract/type inheritance = Implementation inheritance EXTENDING CLASSES - (AKA 'inheritance') - People thought/think inheritance was the be-all of 'Object-Orientedness' = People were/are wrong - AKA 'subclassing'. 'A subclass extends a superclass.' - Why do the Java folk talk like 'extension'? Why not 'inheritance'? - The class contract = Both the externally accessible methods/fields, AND their descriptions = Contract/type inheritance = Implementation inheritance - Extension for specialization (contract preserving) EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); /*HERE*/ b.sayHi(); b.sayBye(); } // b Excitable } // +---+ +------+ | ------>| | $ java Test +---+ | | HI!!!! I'M B1FF!! +------+ Bye. $ Java selects methods based on the type of the OBJECT REFERRED to, NOT the type of the reference variable. EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } Q: Is this a legitimate use of class extension? Why or why not? A: Who knows? EXTENDING CLASSES class Base { /** * Greet the world. */ public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } Q: Is this a legitimate use of class extension? Why or why not? A: Well then, yes. EXTENDING CLASSES class Base { /** * Output the string "Hi." */ public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } Q: Is this a legitimate use of class extension? Why or why not? A: Well then, no. EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Excitable e = new Excitable(); e.sayHi(); e.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Excitable e = new Excitable(); e.sayHi(); e.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Excitable e = new Excitable(); e.sayHi(); e.sayWow(); e.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Excitable e = new Excitable(); e.sayHi(); e.sayWow(); e.sayBye(); } } $ java Test HI!!!! I'M B1FF!! W00H00!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } Test.java:13: cannot resolve symbol symbol : method sayWow () location: class Base b.sayWow(); ^ 1 error EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } Test.java:13: cannot resolve symbol symbol : method sayWow () location: class Base b.sayWow(); How to fix this?? ^ 1 error EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } $ javac Test.java;java Test HI!!!! I'M B1FF!! W00H00!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayWow(); b.sayBye(); } } $ javac Test.java;java Test Be seated. W00H00!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } Test.java:13: cannot resolve symbol symbol : method sayWow () location: class Base b.sayWow(); How to fix this?? ^ 1 error EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? } Test.java:13: cannot resolve symbol symbol : method sayWow () location: class Base b.sayWow(); How to fix this?? ^ 1 error EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? } EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? } EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayBye(){ System.out.println("W00H00!!!! I'M B1FF!!"); System.out.println(super.toString()); } public String toString() { return "foo"; } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? } $ javac Test.java;java Test HI!!!! I'M B1FF!! W00H00!!!! I'M B1FF!! Bye. EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayBye(){ System.out.println("W00H00!!!! I'M B1FF!!"); super.sayBye(); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayTag() { System.out.println("Um."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayTag() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? $ javac Test.java;java Test HI!!!! I'M B1FF!! W00H00!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayTag() { System.out.println("Um."); } public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? $ javac Test.java;java Test Be seated. Corporations first! Bye. $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayTag() { System.out.println("Um."); }// Is "Um." appropriate? public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? What if everybody needs a tagline but there's no sensible default? EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayTag() { System.out.println("Um."); }// Is "Um." appropriate? public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? What if everybody needs a tagline but there's no sensible default? -> Make an abstract method. EXTENDING CLASSES - ABSTRACT CLASS PREVIEW class Base { public void sayHi() { System.out.println("Hi."); } public abstract void sayTag() ; public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? An 'abstract' method says: Every 'concrete' class that is extended from me must define this method, but I'm not saying how to do it. EXTENDING CLASSES - ABSTRACT CLASS PREVIEW class Base { public void sayHi() { System.out.println("Hi."); } public abstract void sayTag() ; public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? $ javac Test.java;java Test Test.java:1: Base is not abstract and does not override abstract method sayTag() in Base $ EXTENDING CLASSES - ABSTRACT CLASS PREVIEW abstract class Base { public void sayHi() { System.out.println("Hi."); } // public abstract void sayTag() ; public void sayBye() { System.out.println("Bye."); } } class SupremeCourtJudge extends Base { public void sayHi() { System.out.println("Be seated."); } public void sayTag() { System.out.println("Corporations first!"); } } public class Test { public static void main(String[] args) { Base b = new SupremeCourtJudge(); b.sayHi(); b.sayTag(); //We have to know more about what's going on here. b.sayBye(); //Why do we want to sayWow here? Is that just part } //of saying hi? Or part of saying bye? Or something } //separate that every Base does? $ javac Test.java;java Test Be seated. Corporations first! Bye. $ EXTENDING CLASSES - TRAP: 'BASE CLASS CREEP' class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } Test.java:13: cannot resolve symbol symbol : method sayWow () location: class Base b.sayWow(); How to fix this?? ^ 1 error EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); ((Excitable) b).sayWow(); b.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); ((Excitable) b).sayWow(); b.sayBye(); } } $ javac Test.java $ java test HI!!!! I'M B1FF!! W00H00!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Base(); b.sayHi(); ((Excitable) b).sayWow(); b.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Base(); b.sayHi(); ((Excitable) b).sayWow(); b.sayBye(); } } $ javac Test.java $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Base(); b.sayHi(); ((Excitable) b).sayWow(); b.sayBye(); } } $ javac Test.java $ java test Hi. Exception in thread "main" java.lang.ClassCastException at Test.main(Test.java:13) $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } $ javac Test.java; java Test HI!!!! I'M B1FF!! Bye. $ EXTENDING CLASSES class Base { final public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } EXTENDING CLASSES class Base { final public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } public void sayWow() { System.out.println("W00H00!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayWow(); b.sayBye(); } } $ javac Test.java Test.java:6: sayHi() in Excitable cannot override sayHi() in Base; overridden method is final public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } ^ 1 error $ EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Base(); b.sayHi(); b.sayBye(); } } EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("HI!!!! I'M B1FF!!"); } } public class Test { public static void main(String[] args) { Base b = new Base(); b.sayHi(); b.sayBye(); } } $ javac Test.java;java Test Hi3 Bye. $ EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } $ javac Test.java;java Test L33T! Bye. $ EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } EXTENDING CLASSES class Base { int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } $ javac Test.java;java Test L33T! Bye. 3 $ EXTENDING CLASSES class Base { private int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } EXTENDING CLASSES class Base { private int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } $ javac Test.java;java Test Test.java:7: num has private access in Base public void sayHi() { System.out.println("L"+num+num+"T!"); } .. Test.java:14: num has private access in Base System.out.println(b.num); .. $ EXTENDING CLASSES class Base { protected int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } EXTENDING CLASSES class Base { protected int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } $ javac Test.java;java Test L33T! Bye. 3 $ EXTENDING CLASSES class Base { protected int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } $ javac Test.java;java Test L33T! Bye. 3 $ ??? This ain't no C++.. -> But general rule of FIELDS SHOULD BE PRIVATE still generally applies. EXTENDING CLASSES class Base { private int num = 3; public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+num+num+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.num); } } $ javac Test.java;java Test Test.java:7: num has private access in Base public void sayHi() { System.out.println("L"+num+num+"T!"); } ^ Test.java:7: num has private access in Base ..etc.. EXTENDING CLASSES class Base { private int num = 3; public int getNum() { return num; } public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+getNum()+getNum()+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.getNum()); } } $ javac Test.java;java Test L33T! Bye. 3 $ EXTENDING CLASSES final class Base { private int num = 3; public int getNum() { return num; } public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+getNum()+getNum()+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.getNum()); } } EXTENDING CLASSES final class Base { private int num = 3; public int getNum() { return num; } public void sayHi() { System.out.println("Hi"+num); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L"+getNum()+getNum()+"T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); System.out.println(b.getNum()); } } $ javac Test.java;java Test Test.java:7: cannot inherit from final Base class Excitable extends Base { $ EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L33T!"); } } public class Test { public static void main(String[] args) { Base b = new Excitable(); b.sayHi(); b.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L33T!"); } } class Irritable extends Excitable { public void sayHi() { System.out.print("DON'T SAY "); super.sayHi(); } } public class Test { public static void main(String[] args) { Base b = new Irritable(); b.sayHi(); b.sayBye(); } } EXTENDING CLASSES class Base { public void sayHi() { System.out.println("Hi."); } public void sayBye() { System.out.println("Bye."); } } class Excitable extends Base { public void sayHi() { System.out.println("L33T!"); } } class Irritable extends Excitable { public void sayHi() { System.out.print("DON'T SAY "); super.sayHi(); } } public class Test { public static void main(String[] args) { Base b = new Irritable(); b.sayHi(); b.sayBye(); } } $ javac Test.java;java Test DON'T SAY L33T! Bye. $ QUIZ 3 RETURN