Lecture 8: Polymorphism & Class Design CSE 116/504 – Intro. To Computer Science for Majors II Lecture 8: Polymorphism & Class Design
Inheritance Composition Sharing is Caring Often need to write classes sharing actions & data Could just cut-and-paste code between the classes If When bug found, must remember to fix both copies Cutting-and-pasting takes effort & have better things to Languages like Java offer two possible solutions: Inheritance & Composition
Use a field to compose classes Composition Typically used for cases with a “has-a” relationship Student has a full name Full name has a first name Car has an engine Rectangle has an upper-right vertex Use a field to compose classes So we would add name field to Student class firstName field in FullName class If must use data externally, add getters & setters
Inheritance “Is-a” relationships implemented via inheritance Automobile is a Vehicle Car is a Vehicle Truck is an Automobile Car is an Automobile extends explicitly specifies superclass for class Can skip & class automatically extends Object
Class Hierarchy Example public class Vehicle {…} public class Automobile extends Vehicle {…} public class Car extends Automobile {…} public class Truck extends Automobile {…} Object Vehicle Automobile Car Truck
Inheritance Key Concept #3 Automatically inherit fields & methods: Can override methods; NEVER redeclare fields
Overriding Methods Subclasses can safely redeclare inherited method "Overloaded" if different signature used in subclass Method said to be "overridden" if signatures identical Specializes method in subclass, this is not required Method changed only for subclass & its subclasses Original used by superclass & other classes, however Execution depends on this - instance used to select
Overriding Methods Within override, can call method in superclass Only while overriding method – cannot call elsewhere Allows reusing inherited method as part of new method super.methodName(…) to call method Chaining illegal super.super.methodName(…) Cannot make less accessible when overriding However, method can make more accessible Legal calls must remain legal, but can allow for more
Overriding Methods Within override, can call method in superclass Only while overriding method – cannot call elsewhere Allows reusing inherited method as part of new method super.methodName(…) to call method Chaining illegal super.super.methodName(…) Cannot make less accessible when overriding However, method can make more accessible Legal calls must remain legal, but can allow for more
abstract Methods Can declare methods as abstract Methods cannot be defined; promise future functionality Methods declared & must have params, return type, etc. Bodies are illegal; declaration only lists signature public abstract void foo(int i); public abstract Beer bar(String o); Exist for inheritance when each subclass differs Body eventually defined, so can method calls legal Subclasses must override, so allows specialization
abstract Methods Key Concept #1 Make method abstract WHEN actually use subclasses & method differs in each
abstract Methods public class DataFile { File dataFile; public abstract ArrayList loadFile(); public ArrayList getData(String filename){ dataFile = new File(filename); // More code handling file would be here ArrayList data = loadFile(); return Collections.sort(data); } } public class CSVDataFile extends DataFile { public ArrayList loadFile() { /* … */ } } public class ExcelDataFile extends DataFile { public ArrayList loadFile() { /* … */ }
abstract class When you write class with abstract methods Class considered abstract no matter declaration abstract classes similar to regular classes… static & non-static fields allowed in class Class will always extend exactly 1 other class Mix of abstract & normal methods can be included May use default one or may define a constructor Can be extended by other classes
abstract class When you write class with abstract methods Class considered abstract no matter declaration abstract classes similar to regular classes… …but cannot instantiate abstract class And abstract methods inherited by subclasses
abstract class When you write class with abstract methods Class considered abstract no matter declaration abstract classes similar to regular classes… …but cannot instantiate abstract class And abstract methods inherited by subclasses But subclass can override method & make it concrete
Abstract Class Key Concept #1 Can define fields; Can define methods; Can declare abstract methods; CANNOT be instantiated
Interfaces in Real World Everyone should give me colored cloths in wallets Boring pictures on these unimportant papers
Interfaces in Real World Everyone should give me colored cloths in wallets Boring pictures on these unimportant papers
Interfaces in Real World Everyone should give me colored cloths in wallets Boring pictures on these unimportant papers In return, will share fun trip pictures (when I get back)
Interfaces Can only declare important constant fields static final must be used with any fields it declares Traditionally declares public abstract methods Methods callable anywhere with any implementing class But interface only a promise: class will define method
Interfaces Can only declare important constant fields static final must be used with any fields it declares Traditionally declares public abstract methods Methods callable anywhere with any implementing class But interface only a promise: class will define method
More Real World Interfaces (top) “Cheques :)” by guilherme jofili is licensed under CC BY 2.0 (bottom) Image of check from State of California in public domain
(Pre-Java 8) Interface Key Concept #1 Promise functionality & identify classes delivering it
(Pre-Java 8) Interface Key Concept #2 Define static final fields; Declare abstract methods; CANNOT be instantiated
Classes With Interfaces Classes implement interfaces to complete IOU Makes implementing classes define interface's methods No limit on number of interfaces class implements Multiple inheritance issues ignored -- methods lack body Unrelated to superclass chosen or used by a class Classes must implement all interface’s methods Includes methods inherited from super-interface
(Pre-Java 8) Interface Key Concept #3 Classes implement interface(s): define the methods; CAN be instantiated
Implementing Interfaces public class Square implements Drawable { private Color c; private int x, y, side; public Square(Color col, int len) { c = col; side = len; } public void setColor(Color col){ c=col; } public Color getColor() { return c; } public void draw(Graphics g) { g.drawRect(x, y, side, side, c); } }
Implementing Interfaces public class Oval implements Drawable { private Color c; private int x, y, majRad, minRad; public Oval(Color co, int maj, int min){ c = co; majRad = maj; minRad = min; } public void setColor(Color col){ c=col; } public Color getColor() { return c; } public void draw(Graphics g) { g.drawOval(x, y, majRad, minRad, c); } }
Using Interfaces Cannot instantiate an interface… Not possible, since only create instances of class Variables of interface type perfectly legal Variable can refer to implementing class instance Methods must be implemented in actual class In Java, which method called by instance type public void drawRed(Drawable d, Graphics g) { d.setColor(Color.red); d.draw(g); }
Using Interfaces Cannot instantiate an interface… Not possible, since only create instances of class Variables of interface type perfectly legal Variable can refer to implementing class instance Methods must be implemented in actual class In Java, which method called by instance type public void drawRed(Drawable d, Graphics g) { d.setColor(Color.red); d.draw(g); }
Using Interfaces Cannot instantiate an interface… Not possible, since only create instances of class Variables of interface type perfectly legal Variable can refer to implementing class instance Methods must be implemented in actual class In Java, which method called by instance type public void drawRed(Drawable d, Graphics g) { d.setColor(Color.red); d.draw(g); }
What About Constructors? Constructor initializes fields to setup for future uses "is-a" relationship means subclass needs similar setup Subclass may need more, since it can add fields Car is-a Vehicle but does more; may need changes Instantiation uses constructor, but that is ONLY use Classes define own constructors, but are they inherited? Could we even call it? Name is same as superclass
Inheritance Not Always Equal Superclass constructor still needed by subclass… When creating subclass (kinda) instantiating superclass Instance is-a superclass instance (hence the kinda need) Somehow need to initialize instances superclass part …but inherited differently than methods & fields Image of "Treasury of Human Inheritance" in Public Domain. Downloaded from: https://archive.org/stream/treasuryofhumani01bull#page/n5/mode/2up
Constructor Key Concept #1 Image of "Chain Up Area" sign used under a Creative Commons Attribution 2.0 Generic license. The original is by CGP Grey (http://www.cgpgrey.com) and was downloaded from: https://commons.wikimedia.org/wiki/File:2006-08-01_-_11_-_Road_Trip_-_Day_09_-_United_States_-_Montana_-_Sign_-_Chain_Up_Area_-_Bondage_on_t_4889354750.jpg
Java Constructor Chains All Java classes MUST reuse superclass constructor Already initializes fields in superclass Provides us with way to maximize laziness Allows sharing constructor code within class, too Still want to avoid copying code Often do identical work initializing fields Constructors increase laziness through chaining
Java Constructor Chains All Java classes MUST reuse superclass constructor Already initializes fields in superclass Provides us with way to maximize laziness Allows sharing constructor code within class, too Still want to avoid copying code Often do identical work initializing fields Constructors increase laziness through chaining
Chain Usage Explained Constructors start by chaining to another one Must either be constructor in class or in superclass Circular chains forbidden – Java will not let it compile Multiple hops fine, but (eventually) must reach superclass Chain usually implicit (e.g., all your code so far) Unless explicitly stated, calls constructor in superclass Constructor without params chained, lacking more info Means must have no constructor or one with no params Cannot implicit chain otherwise; need that constructor Picture of bike chain taken by George Hodan and entered into the public domain. Original image is available at: http://www.publicdomainpictures.net/view-image.php?image=175884&picture=bicycle-chains
Constructor Key Concept #2 Often not explicitly coded, but Constructor must chain to superclass
Chain Usage Explained Explicitly chain by using this(…) or super(…) Must be first command since chaining occurs at start Call matching constructor in same class using this(…) super(…) calls superclass constructor that matches Only needed when not using implicit constructor chain Constructor chaining works just like method call Types and order of arguments must match parameters Still just Java -- cannot violate access protection Object being created is this (implicit parameter) in call Picture of chain taken by Rusty Tanton and used under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 license. The original image is available at: https://www.flickr.com/photos/rustytanton/2096814314
Chain Usage Explained Explicitly chain by using this(…) or super(…) Must be first command since chaining occurs at start Call matching constructor in same class using this(…) super(…) calls superclass constructor that matches Only needed when not using implicit constructor chain Constructor chaining works just like method call Types and order of arguments must match parameters Still just Java -- cannot violate access protection Object being created is this (implicit parameter) in call Picture of chain taken by Rusty Tanton and used under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 license. The original image is available at: https://www.flickr.com/photos/rustytanton/2096814314
Constructor Key Concept #3 Chain call must start ALL constructors
Constructors Not Inherited Constructors not "inherited"; only used via chaining Trying to call superclass constructor using new illegal Constructor accessible, but not same as inherited (?) Many classes do not define constructor of their own When not defined, automatically get one with no params Implied chain used by this implicit constructor For it to work, superclass must have 0 param constructor
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Must match CSticker constructor parameters Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); } Must match CSticker constructor parameters
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
needs superclass constructor without params Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); } Lacking explicit chain (this(…) or super(…)) needs superclass constructor without params
needs superclass constructor without params Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(clr, type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); } Lacking explicit chain (this(…) or super(…)) needs superclass constructor without params
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(clr, type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(clr, type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
must match constructor parameters Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(clr, type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); } Arguments to calls of this(…) or super(…) must match constructor parameters
must match constructor parameters Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); } Arguments to calls of this(…) or super(…) must match constructor parameters
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(type); text = type; color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(type); color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
Stickers public class Sticker { String text; public Sticker(String words) { text = words; } public void printMe() { System.out.println(text); } } public class CSticker extends Sticker { String color; public CSticker(String clr, String type) { super(type); color = clr; } public CSticker(String type) { this("blue", type); } public static void main(String[] args) { Sticker s = new Sticker(“boo”); CSticker cs = new CSticker(“hoo”); s.printMe(); cs.printMe(); }
About To Get a Little Bumpy
Working with Class Types To use & assign values, must consider two issues Can it work? Instances' types can crash code Will object in heap have field used or method called? Is-A relationship exist? Program crashes if no Is-A exists
Working with Class Types To use & assign values, must consider two issues Can it work? Instances' types can crash code Will object in heap have field used or method called? Is-A relationship exist? Program crashes if no Is-A exists "146/365 square peg into a round hole" by rosipaw used under a Creative Commons Attribution-NonCommercial-ShareAlike 2.0 Generic license. Original image was downloaded from: https://www.flickr.com/photos/rosipaw/4643095630
Working with Class Types To use & assign values, must consider two issues Can it work? Instances' types can crash code Will object in heap have field used or method called? Is-A relationship exist? Program crashes if no Is-A exists When executed, placing square peg into round hole? Will it compile? Variables' types match uses Bytecodes needed to run & compiler only sees variables Computers stupid and compiler cannot know instances
Polymorphism Key Concept #1 Compiler looks at VARIABLES
Polymorphism Key Concept #1 Execution depends on INSTANCES
Compiler & Polymorphism Inheritance based on idea: subclass is-a superclass If superclass needed, subclass acceptable to be used Compiler knows that all assignments & uses will be safe Opposite is not true; subclass may add to superclass Allows subclass into superclass assignments Happy compiling legal method calls & field uses, also Only checking program for safety, not correctness
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Dog(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark());
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Dog(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Dog Is-A Mammal so this compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Dog(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Fox & Dog unrelated; this will not compile
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Fox Is-A Fox so this now compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Dog Is-A Mammal so this compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Dog lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Dog Is-A Mammal so this compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Every class Is-An Object; this compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); Fox Is-A Mammal; this is safe & compiles
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); makeNoise() not in Mammal or Dog; Makes no sense & should not compile
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); makeNoise() not in Mammal or Dog; Makes no sense & should not compile
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); bark() is in Dog; this can be executed
Compiler & Polymorphism public class Mammal { public int getNumLegs() {/* This is pretend example, okay? */} } public class Fox extends Mammal { public String makeNoise() {/* What does the fox say? */} } public class Dog extends Mammal { public String bark() { return "Woof"; } public static void main(String[] args) { Mammal generic = new Dog(); Fox quick = new Fox(); Object lazy = new Mammal(); int legs = quick.getNumLegs(); System.out.println(generic.makeNoise()); System.out.println(generic.bark()); bark() is NOT in Mammal; Compiler only uses VARIABLES. Help!!!
Typecasting Typecasting exists to “assist” compiler with code Changes variable’s type so code can be compiled Only helps the compiler; cannot affect instance's type Does not make code legal; only helps code compile Even if compiler accepts it, a lie is a lie is a lie Trades identified bug for unknown crash; not a good idea
Typecasting Typecasting exists to “assist” compiler with code Changes variable’s type so code can be compiled Only helps the compiler; cannot affect instance's type Does not make code legal; only helps code compile Even if compiler accepts it, a lie is a lie is a lie Trades identified bug for unknown crash; not a good idea
Narrowing Conversions Java will flag as an error any narrowing conversions Compiler uses variable's types; must follow IS-A pattern Can only use variables, even if instances types "obvious" Typecast required to tell compiler code is okay Crashes if instance types do not work, not a real "fix" Drawable obj = new Oval(...);
Narrowing Conversions Java will flag as an error any narrowing conversions Compiler uses variable's types; must follow IS-A pattern Can only use variables, even if instances types "obvious" Typecast required to tell compiler code is okay Crashes if instance types do not work, not a real "fix" Drawable obj = new Oval(...); Oval sad = obj; // Compiler Error
Narrowing Conversions Java will flag as an error any narrowing conversions Compiler uses variable's types; must follow IS-A pattern Can only use variables, even if instances types "obvious" Typecast required to tell compiler code is okay Crashes if instance types do not work, not a real "fix" Drawable obj = new Oval(...); Oval sad = obj; // Compiler Error Oval glad = (Oval)obj; // works!
Polymorphism Key Concept #3 Typecast only if certain of INSTANCE'S type
Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(super1.otherMethod()); SubClass sub2 = super1; System.out.println(sub2.getMyString());
Compiler uses variable's type and super1's type is SuperClass Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(super1.otherMethod()); SubClass sub2 = super1; System.out.println(sub2.getMyString()); Compiler uses variable's type and super1's type is SuperClass
Typecast tells compiler to pretend it has different type Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(((SubClass)super1).otherMethod()); SubClass sub2 = super1; System.out.println(sub2.getMyString()); Typecast tells compiler to pretend it has different type
Cannot assign superclass variable to subtype variable Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(((SubClass)super1).otherMethod()); SubClass sub2 = super1; System.out.println(sub2.getMyString()); Cannot assign superclass variable to subtype variable
Typecast tells compiler to pretend it has different type Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(((SubClass)super1).otherMethod()); SubClass sub2 = (SubClass)super1; System.out.println(sub2.getMyString()); Typecast tells compiler to pretend it has different type
Polymorphism Key Concept #4 INSTANCE'S type specifies method executed
Inheritance Example public class SuperClass { public String getMyString() { return "SUPER"; } } public class SubClass extends SuperClass { public String getMyString() { return "sub " + super.getMyString(); } public String otherMethod() { return "other"; } public static void main(String[] args) { SubClass sub = new SubClass(); SuperClass super1 = new SuperClass(); System.out.println(sub.getMyString()); System.out.println(super1.getMyString()); System.out.println(sub.otherMethod()); super1 = sub; System.out.println(super1.getMyString()); System.out.println(((SubClass)super1).otherMethod()); SubClass sub2 = (SubClass)super1; System.out.println(sub2.getMyString());
abstract Methods Key Concept #1 Make method abstract WHEN actually use subclasses & method differs in each
Abstract Class Key Concept #1 Can define fields; Can define methods; Can declare abstract methods; CANNOT be instantiated
(Pre-Java 8) Interface Key Concept #2 Define static final fields; Declare abstract methods; CANNOT be instantiated
(Pre-Java 8) Interface Key Concept #3 Classes implement interface(s): define the methods; CAN be instantiated
Inheritance is automatic NEVER REDECLARE FIELDS Inheritance Tip #1 Inheritance is automatic NEVER REDECLARE FIELDS Still the most depressing MS clip art ever…
Constructor Key Concept #1 Java Chains Image if a heart made from chains is from public domain. The original image is on the Max Pixel website and can be downloaded from: http://maxpixel.freegreatpicture.com/String-Framework-Embellishment-Heart-Scrapbooking-678039
Constructor Key Concept #1 Often not explicitly coded, but Must chain to superclass constructor
Constructor Key Concept #2 Chaining STARTS constructor
Constructor Key Concept #3 this( /*…*/ ) to chain within class super( /*…*/ ) to chain to superclass
Polymorphism Key Concept #1 Compiler looks at VARIABLES
Polymorphism Key Concept #1 Execution depends on INSTANCES
Polymorphism Key Concept #3 Typecast only if certain of INSTANCE'S type
Polymorphism Key Concept #4 INSTANCE'S type specifies method executed
For Next Lecture Important to do readings before next lecture Website has links to short reading about arrays Section 0.3 from textbook shows usage in Java As you read material, several ideas to consider How are arrays allocated and what is their type? When and why do we need to use brackets ([]) ? As usual, the weekly assignment due next week Due by 12:45PM Monday using AutoLab