Inheritance + Polymorphism
What is Inheritance
• Classes can inherit common state and/or
behavior from other classes
• Parent classes are more generic
• Child classes are more specific • Single-Inheritance
Inheritance
• “A class that is derived from another class is
called a subclass (also a derived class,
extended class, or child class). The class from which the subclass is derived is called a
superclass (also a base class or a parent class).
“
• https://
docs.oracle.com/javase/tutorial/java/IandI/subc lasses.html
Inheritance
• “Excepting Object, which has no superclass,
every class has one and only one direct
superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.”
• https://
Inheritance
• “Classes can be derived from classes that are derived from classes that are derived from
classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the
inheritance chain stretching back to Object. “
• https://
docs.oracle.com/javase/tutorial/java/IandI/subc lasses.html
Inheritance Example
Examples:
Food is a superclass of Fruit, Vegetable, Meat, and Grain
Inheritance Example 2
7
Examples:
Vehicle is a superclass of Air Vehicle, Land Vehicle, and Sea Vehicle
Inheritance Advantages
• Prevents duplicate code for similar classes
– No copy/paste code
– Copy and pasting code makes you look bad!
• Makes programs easier to extend and maintain
– *Usually but not always*
Inheritance Disadvantages
• Harder to program
– Need to think about which attributes and functions belong in which classes
– Harder to design the classes
• Harder to make changes
– If a superclass method is modified, subclass methods may be broken
• Requires more knowledge to work with a single class
– Ancestor + descendent classes
Inheritance Disadvantages
• Not always easy to visualize the inheritance hierarchy
– Example: Throwable class
– https://
docs.oracle.com/javase/8/docs/api/java/lang/Thro wable.html
• Code is harder to understand to programmers not familiar with the inheritance design
– Example:
• MythicalAnimal ma = new Unicorn(); – //Apparently there is a Unicorn class
Animal Example
• Pick an animal and make a class to represent it
– What properties does that animal have
• Private attributes
– What can that animal do
• Functions/methods
Animal Example Continued
• Pick another animal and make a class to
represent it
– What properties does that animal have
• Private attributes
– What can that animal do
Animal Example Continued
• Do these two animals have anything in
common
– Common attributes?
– Common functions?
Animal Example Continued
• Make a superclass for these animal classes
– Take common code and store in the superclass
– Have these animals be a subclass of the new class
extends
• The extends keyword is used by classes to
inherit from another class
• Java does not support multiple inheritance
– A class may only extend a single class
– Interfaces (to be discussed later) are used to
compensate for this restriction
Example - ExtendsExample
• Main.java • A.java
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 17
public class B extends A {
public B() {
numericValue = 2; }
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
}
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 19
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
}
public class B extends A {
public B() {
numericValue = 2; }
}
Override the default constructor and initialize
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 21
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
}
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 23
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
}
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 25
public class B extends A {
public B() {
numericValue = 2; }
}
numericValue is private
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
}
public class B extends A {
public B() {
numericValue = 2; }
}
Could change the scope to protected, but numericValue
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public int getNumericValue() {
return numericValue; }
} 27
public class B extends A {
public B() {
numericValue = 2; }
}
Better solution: Create another constructor in class A to take an
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public A(int numericValue) {
this.numericValue = numericValue;
}
//get method still here
} 28
public class B extends A {
public B() {
numericValue = 2; }
}
Extends Example
public class A {
private int numericValue;
public A() {
numericValue = 1; }
public A(int numericValue) {
this.numericValue = numericValue;
}
//get method still here
} 29
public class B extends A { public B() { super(2); } }
Constructor Invocation
• Constructors are not inherited
• Constructors are invoked (called)
– Implicitly
• If not done explicitly
– Explicitly
• Using super as the first word in the constructor of the subclass
• Must be the first word
Constructor Example
31
public A() {
//statements }
public A() {
super();
//statements }
Implicit super constructor call
Constructor Chaining
• Constructor chaining is where there can be a
long chain of constructors being invoked
Example - ConstructorChaining
• A.java • B.java
• C.java
• D.java
• Trace code
Super
• Not just for constructors
• Super can be used in a subclass to call a method of a super class
• Format
– super.<superclass method name>
Object Class
• Every class inherits from the Object class • Every class is an Object
• Commonly overridden methods
– toString()
– equals() + hashCode()
• https://
docs.oracle.com/javase/8/docs/api/java/lang/O bject.html
toString()
• Represents your class as a String
• Every class has a toString method
– Because the Object class has it
• Classes that do not override the existing toString() method, get the default Object toString() method
• Often used for printing out the class attributes • System.out.println(<some class>)
equals
• Used to determine if two Objects are equal • Always use equals when comparing Objects
– Never use “==“
• If the class is expected to be compared to
another Object, then the equals method should be overridden
• If equals is overridden then hashCode should be overridden
hashCode()
• Used to uniquely identify the object when used
in hash tables
• If hashCode is overridden then equals should be overridden as well
Generating equals and hashCode
Generating equals and hashCode
41
• Choose all the variables that you want to use in your equals comparison
• Usually all the variables are selected
Generating equals and hashCode
• Choose to insert the generated functions as the last member of the class
• These functions are
Generating equals and hashCode
43
• Choose to generate method comments
• Why not?
• Choose to use instanceof to compare types
• Because Josh Bloch says so
• Choose to use blocks in “if” statements
• Makes it easier to read
Note
• Use auto-generated methods carefully
• toString() is better implemented manually
– Possible with the use of StringBuilder for objects
that contain arrays
• You may want to restrict scope on constructors or setters and getters
– You may not want certain ones
Override vs Overload
• Override
– Redefine a superclass method
– When the object calls this method the overridden method gets called and not the method in the
superclass
• Unless the subclass method uses super in its overridden
method
• Overload
– Defines a different method with the same name but a
different number of parameters
What is wrong here?
Public class A {
public boolean equals(A otherInstance) {
//code here }
What is wrong here?
Public class A {
public boolean equals(A otherInstance) {
//code here }
}
47
What is wrong here?
Public class A {
public boolean equals(A otherInstance) {
//code here }
}
@Override Annotation
• Using “@Override” above the method can tell
the compiler that you are overriding the method
• The compiler is your friend not your enemy
• If you incorrectly overload a method instead of overriding it, the compiler will stop your
program from compiling
What is wrong here?
Public class A {
@Override
public boolean equals(A otherInstance) {
//code here }
}
What is wrong here?
Public class A {
@Override
public boolean equals(Object otherInstance) {
//code here }
}
51
Animal Example Continued
• Override the following methods in your animal
classes
– toString()
– equals()
– hashCode()
What is Polymorphism?
• Polymorphism is when a subclass can be used
wherever a superclass can be used
• Example
– Any function that takes an Object as a parameter
can also take any subclasses of an Object as a parameter
Example – Polymorphism Example
• A.java • B.java
• C.java
Example Continued
• A b1 = new B();
– What is happening here?
• b1.getNumericValue()
– Which function gets called?
– A.getNumericValue() or B.getNumericValue()
Declared Type vs. Actual Type
• Declared type
– Type of the variable that is declared
– b1 is declared type A
• Actual Type
– Type the variable is
– new B() Indicates the type of b1 is B
• A superclass can hold subclass types
Dynamic Binding
• The type of the variable is bound at runtime • Functions are chosen by the actual type of the
variable
• A declared object type can be set to hold any
other class type
– Can also be changed during runtime
Casting
• Implicit
– Example: Vehicle vehicle = new Car();
– Can only cast from a subclass to a superclass
– Car car = new Vehicle(); //Does not work
– A car is a vehicle, a vehicle is not necessarily a car
• Explicit
Casting Continued
• Upcasting
– Cast a variable to a superclass type
– Vehicle v = (Vehicle)Car
• A Car is a Vehicle • Downcasting
– Cast a variable to a subclass type
– Car car = (Car)vehicle
• Can try but might fail if the vehicle is not a car
Downcasting
• Use with caution
• Check or use try/catch blocks when attempting to downcast
• Try to avoid explicit casting (up or down)
whenever possible
• Remember equals method
– Used “instanceof” to check the class before
Casting primitives
• Casting primitives creates a new value
• Casting objects does not create a new object
– Except for cases where “new” is used
Common Problem
• A common problem is where you want to have
a list of some class
• The class holding the list can hold any type of
object
• However you are not storing multiply different
types in the list
– You are typically storing just a single type
Generics
• Enforce a user-specified class type
• ArrayList<Integer> list= new ArrayList<Integer>()
– Creates an ArrayList that must store only Integer objects – The generic type is in angle brackets
• “<Integer>”
• https://
docs.oracle.com/javase/8/docs/api/java/util/Arr ayList.html
• “public class ArrayList<E>”
– “<E>” stands for the type of the objects expected
Other Notes
• Using the final keyword for a class modifier
makes the class un-extendable
• Subclasses cannot weaken the scope of superclass methods
– private public = okay