Inheritance and
Polymorphism
COMP2396 Object-Oriented Programming and Java
Dr. Kenneth Wong
Shapes Example
Recall the shapes example in Lecture 2, Owen, the
OO guy, wrote a class for each of the 4 shapes
superclass
Avoid duplicate code by inheritance Shape (more abstract)
Handle specialization by overriding playSound()
rotate()
methods
Square Circle Triangle Amoeba
rotate() rotate() rotate() rotate() {
playSound() playSound() playSound() playSound()
// amoeba-specific
// rotate code
}
playSound() {
A subclass will automatically inherit // amoeba-specific
the members (i.e., instance variables subclasses // sound code
and methods) of its superclass }
(more specific)
1
Inheritance Overview
When designing with inheritance, put common code in a class
and make it the superclass of the other more specific classes
(which then become its subclasses)
In Java, we say that a subclass extends its superclass
There exists an inheritance relationship between a subclass
and its superclass where the subclass inherits the members
(i.e., instance variables and methods) of its superclass
A subclass can also add new instance variables and methods
of its own, and can override the methods it inherits from its
superclass (specialization!)
Instance variables are not overridden because they don’t need
to be (they don’t define any behavior). A subclass can give an
inherited instance variable any value it chooses
2
Example: SuperHero
SuperHero
suit instance variables
specialPower (state)
useSpecialPower() methods
putOnSuit() (behavior)
Ironman
Superman
overriding useSpecialPower()
putOnSuit()
methods
Ironman has specific requirements
Superman doesn’t need any for his suit and special powers, so
behavior that’s unique, so he both useSpecialPower() and putOnSuit()
doesn’t override any method are overridden in the Ironman class
3
Example: Doctor
public class Doctor { Doctor
boolean workAtHospital; workAtHospital
void treatPatient() { /* perform a checkup */ } treatPatient()
}
public class FamilyDoctor extends Doctor {
boolean makesHouseCalls; Surgeon FamilyDoctor
void giveAdvice() { /* give homespun advice */ } makesHouseCalls
}
treatPatient() giveAdvice()
makeIncision()
public class Surgeon extends Doctor {
void treatPatient() { /* perform surgery */ }
void makeIncision() { /* make incision */ }
}
4
Example: Doctor
• How many instance variables does
Surgeon have? Doctor
workAtHospital
• How many instance variables does treatPatient()
FamilyDoctor have?
• How many methods does Doctor have?
• How many methods does Surgeon have? Surgeon FamilyDoctor
makesHouseCalls
• How many methods does FamilyDoctor treatPatient() giveAdvice()
have? makeIncision()
• Can a FamilyDoctor do treatPatient()?
• Can a FamilyDoctor do makeIncision()?
5
Example: Doctor
• How many instance variables does
Surgeon have? 1 Doctor
workAtHospital
• How many instance variables does
FamilyDoctor have? 2
treatPatient()
• How many methods does Doctor have? 1
• How many methods does Surgeon have? 2 Surgeon FamilyDoctor
makesHouseCalls
• How many methods does FamilyDoctor treatPatient() giveAdvice()
have? 2 makeIncision()
• Can a FamilyDoctor do treatPatient()? Yes
• Can a FamilyDoctor do makeIncision()? No
6
Designing an Inheritance Tree
Owen was asked to design a simulation program that lets
user throw a bunch of different animals into an environment
to see what happens
Initially, the program should support 6 kinds of animals:
New kinds of animals, however, may be added to the program
at any time
Owen began by designing an inheritance tree for the animals
7
Designing an Inheritance Tree
1 Look for objects that have common
attributes and behaviors
Common attributes: Common behaviors:
food makeNoise()
hunger eat()
location sleep()
roam()
8
Designing an Inheritance Tree
Animal
food
2 Design a class that represents the hunger
common state and behavior location
makeNoise()
eat()
sleep()
roam()
Using inheritance avoids
duplicating code in the
subclasses
Hippo
Dog
Cat Wolf
Tiger
Lion
9
Designing an Inheritance Tree
Animal
food
3 Decide if a subclass needs behavior hunger
that is specific to that particular location
subclass type makeNoise()
eat()
sleep()
roam()
Hippo
Dog
Cat Wolf
makeNoise()
Tiger eat()
makeNoise()
Lion makeNoise()
makeNoise()
eat()
makeNoise() eat()
eat()
makeNoise() eat()
eat()
10
Designing an Inheritance Tree
Animal
food
4 Look for more opportunities to use hunger
abstraction, by finding 2 or more location
subclasses that might share common makeNoise()
eat()
behavior sleep()
roam()
Hippo
Dog
Cat Wolf
makeNoise()
Tiger eat()
makeNoise()
Lion makeNoise()
makeNoise()
eat()
makeNoise() eat()
eat()
makeNoise() eat()
eat()
11
Designing an Inheritance Tree
Animal
food
4 Look for more opportunities to use hunger
abstraction, by finding 2 or more location
subclasses that might share common makeNoise()
eat()
behavior sleep()
roam()
Feline Canine
roam()
roam()
Hippo
Dog
Cat Wolf
makeNoise()
Tiger eat()
makeNoise()
Lion makeNoise()
makeNoise()
eat()
makeNoise() eat()
eat()
makeNoise() eat()
eat()
12
Which method is called?
The Wolf class has 4 methods: 1 inherited from Animal
Animal, 1 inherited from Canine, and 2 food
hunger
overridden in the Wolf class location
makeNoise()
eat()
Which version of these methods will get called sleep()
when they are called on a Wolf reference? roam()
Wolf w = new Wolf();
w.makeNoise(); Canine
w.roam();
w.eat(); roam()
w.sleep();
Wolf
makeNoise()
eat()
13
Which method is called?
The Wolf class has 4 methods: 1 inherited from Animal
Animal, 1 inherited from Canine, and 2 food
hunger
overridden in the Wolf class location
makeNoise()
eat()
Which version of these methods will get called sleep()
when they are called on a Wolf reference? roam()
Wolf w = new Wolf();
w.makeNoise(); Canine
w.roam();
w.eat(); roam()
w.sleep();
Wolf
makeNoise()
eat()
14
Which method is called?
When a method is called on an object Animal
reference, the most specific version of the food
hunger
method for that object type will be called location
makeNoise()
In other words, the lowest one in the eat()
sleep()
inheritance tree wins! roam()
In calling a method on a reference to a
Wolf object, the JVM starts looking first in Canine
the Wolf class
roam()
If the JVM doesn’t find a version of the
method in the Wolf class, it starts walking
up the inheritance hierarchy until it finds a Wolf
match
makeNoise()
eat()
15
Which method is called?
It is possible to call an overridden method Animal
food
of the superclass using the keyword super hunger
location
makeNoise()
Example eat()
sleep()
roam()
public class Animal {
public void roam() {
System.out.println("Animal roams");
} Canine
// ...
roam()
}
public class Canine extends Animal {
public void roam() { Wolf
super.roam(); // roam() in Animal class is called
System.out.println("Canine roams"); makeNoise()
} eat()
}
16
Which method is called?
Example Animal
food
public class SuperTestDrive { hunger
location
public static void main(String[] args) { makeNoise()
Canine c = new Canine(); eat()
c.roam(); sleep()
roam()
}
}
Canine
Sample output roam()
Animal roams
Canine roams
Wolf
makeNoise()
eat()
17
Access Control
A superclass can choose whether or not it wants a
subclass to inherit a particular member by the
access level assigned to that particular member
public members are inherited
private members are not inherited
When a subclass inherits a member, it is as if the
subclass defined the member itself
A private instance variable of the superclass, which
is not inherited, may still be accessed through the
inherited public getter and public setter
18
Access Control
Access Access Class Package Sub- World
level modifier class
more private private Y N N N
restrictive
default (none) Y Y N N
protected protected Y Y Y N
less
restrictive public public Y Y Y Y
• private means that only code within the same class can
access it
• default means that only code within the same package as
the class with the default member can access it
• protected works just like default except it also allows
subclasses outside the package to inherit the protected
member
• public means any code anywhere can access it
19
IS-A Relationship
When one class inherits from another, we say the
subclass extends its superclass
Recall that there exists a IS-A relationship between a
subclass and its superclass: a subclass object IS-A
superclass object (which means a subclass object can
do anything that a superclass object can do)
To check whether one thing, say X, should extend
another, say Y, apply the IS-A test: check if it makes
sense to say X IS-A Y?
Examples:
Triangle IS-A Shape (Triangle extends Shape)
Surgeon IS-A Doctor (Surgeon extends Doctor)
20
IS-A Relationship
The IS-A test works anywhere in the Animal
inheritance tree
food
hunger
location
If class B extends class A, and class C makeNoise()
eat()
extends class B, then class C passes the IS-A sleep()
roam()
test for both class B and class A
Example Canine
Wolf IS-A Canine (Wolf extends Canine)
roam()
Canine IS-A(n) Animal (Canine extends Animal)
Wolf IS-A(n) Animal (Wolf extends Animal)
Wolf
Note that the IS-A relationship works in only
one direction! makeNoise()
eat()
21
HAS-A Relationship
What about “Tub extends Bathroom”?
To check whether Tub should extend
Bathroom, ask the question: “Does it
make sense to say Tub IS-A Bathroom?”
“Tub IS-A Bathroom” is definitely false,
and therefore Tub should not extend Bathroom
Tub and Bathroom are joined by a HAS-A relationship
“Bathroom HAS-A TUB” means that Bathroom has a
Tub instance variable
22
Rules in Inheritance Design
When designing with inheritance
DO use inheritance when one class is a more specific
type of a superclass
DO consider inheritance when common behavior
should be shared among multiple classes of the
same general type
DO NOT use inheritance just for reusing code from
another class if the relationship between the subclass
and superclass violates either of the above 2 rules
DO NOT use inheritance if the subclass and the
superclass do not pass the IS-A test
23
Method Overriding
Recall that a subclass object IS-A superclass
object, and it can do anything that the superclass
object can do
When a subclass overrides a method inherited from
its superclass, it must make sure that
Argument list must be the same
Return type must be compatible (i.e., either the same
type or a subclass type)
The method cannot be less accessible (i.e., either the
same or friendlier access level)
24
Method Overriding
Example
public class Dog {
public void makeNoise() {
System.out.println("Woof!");
}
}
public class Poodle extends Dog {
public void makeNoise() {
System.out.println("Ruff! Ruff!");
}
}
25
Method Overriding
Example same
argument lists
public class Dog {
public void makeNoise() {
System.out.println("Woof!");
same }
access }
levels
public class Poodle extends Dog {
public void makeNoise() {
System.out.println("Ruff! Ruff!");
}
}
same
return types 26
Method Overloading
Method overloading is nothing more than having 2
or more methods with the same name but different
argument lists
It has nothing to do with inheritance and
polymorphism
For overloaded methods
Argument lists must be different
Return types can be different
Access levels can be different
27
Method Overloading
Example
public class Dog {
public void makeNoise() {
System.out.println("Woof!");
}
}
public class Poodle extends Dog {
public void makeNoise(int n) {
for (int i = 0; i < n; i++) {
System.out.println("Ruff! Ruff!");
}
}
}
28
Method Overloading
Example different
argument lists
public class Dog {
public void makeNoise() {
System.out.println("Woof!");
}
}
public class Poodle extends Dog {
public void makeNoise(int n) {
for (int i = 0; i < n; i++) {
System.out.println("Ruff! Ruff!");
}
}
}
29
Benefits of Inheritance
Get rid of duplicate code
Behaviors common to a group of classes are
abstracted out and put in a superclass
Only one place to update when modifications of these
common behaviors are needed
In Java, all classes that extend the superclass will
automatically use the new version. Hence no need to
touch the subclasses, not even recompiling them!
30
Benefits of Inheritance
Define a common protocol for a group of classes
Establishes a contract which guarantees all classes
that extend a superclass have all the inheritable
methods of that superclass
Allows any subclass object be substituted where the
superclass object is expected (i.e., polymorphism)
Example:
Animal animal1 = new Dog();
Animal animal2 = new Cat();
31
The Way Polymorphism Works
The 3 steps of object declaration, creation and
assignment
1. Declare a reference variable
2. Create an object on the heap
3. Assign the object reference to the variable
1 3 2
Dog myDog = new Dog();
Dog 2 Create a Dog
1 Declare a 3 Assign the object object object on the
reference myDog reference to the heap
variable variable
Dog
Here, both the reference type and the object
type are the same (i.e., both are Dog)
32
The Way Polymorphism Works
With polymorphism
The reference type can be a superclass of the actual object
type
Any object that passes the IS-A test for the declared type
of the reference variable can be assigned to that reference
variable
Animal myDog = new Dog();
Dog
object
myDog
Animal
The reference variable type is declared as
Animal, but the object created is a Dog object
33
Benefits of Polymorphism
Can do things like polymorphic arrays, polymorphic
argument and polymorphic return types
Makes it possible to write code that does not have to
change when new subclass types are introduced
Example
Animal[] animals = new Animal[6];
animals[0] = new Dog();
animals[1] = new Cat();
animals[2] = new Wolf():
animals[3] = new Hippo():
animals[4] = new Lion();
animals[5] = new Tiger();
for (int i = 0; i < 6; i++) { Calling the methods on the actual
animals[i].makeNoise(); subclass objects in runtime
animals[i].eat();
} 34
Benefits of Polymorphism
Example
public class Vet {
public void giveShot(Animal a) {
// gives shot to the Animal
a.makeNoise();
}
}
public class PetOwner {
public void start() {
Vet v = new Vet();
Dog d = new Dog();
Hippo h = new Hippo();
v.giveShot(d);
v.giveShot(h); This will work for future
} Animal subclasses as well
}
35