135 Week 8
135 Week 8
Week 8
By
Javed Siddique
Introduction
Inheritance and polymorphism are key concepts
of Object Oriented Programming
Inheritance facilitates the reuse of code
A subclass inherits members (data and methods)
from all its ancestor classes
The subclass can add more functionality to the
class or replace some functionality that it
inherits.
Polymorphism simplifies code by automatically
using the appropriate method for a given object.
Polymorphism also makes it easy to extend
Inheritance
A superclass corresponds to a general class, and
a subclass is a specialization of the superclass.
E.g. Account, Checking, Savings.
Behavior and data common to the subclasses is
often available in the superclass.
E.g. Account number, owner name, data opened.
Each subclass provides behavior and data that is
relevant only to the subclass.
E.g. Minimum balance for checking a/c, interest rate
and computation for savings account.
The common behavior is implemented once in
the superclass and automatically inherited by the
subclasses.
Defining Classes with Inheritance
Case Study:
Suppose we want implement a class roster that
contains both undergraduate and graduate students.
Each student’s record will contain his or her name,
three test scores, and the final course grade.
The formula for determining the course grade is
different for graduate students than for undergraduate
students.
Modeling Two Types of Students
public Student( ) {
this("No Name");
}
public Student(String studentName) {
name = studentName;
test = new int[NUM_OF_TESTS];
courseGrade = "****";
}
public String getCourseGrade( ) {
return courseGrade;
}
public String getName( ) {
return name;
}
public int getTestScore(int testNumber) {
return test[testNumber-1];
}
public void setName(String newName) {
name = newName;
}
public void setTestScore(int testNumber, int testScore) {
test[testNumber-1] = testScore;
}
}
Example: GraduateStudent
+ NUM_OF_TESTS
# name
New visibility # test
modifier: # # courseGrade
protected + Student(): void
+ Student(String): void
+ getCourseGrade(): String
+ getName(): String
+ getTestScore(int): int
+ setName(String): void
+ setTestScore(int, int): void
UndergraduateStudent GraduateStudent
sub.methodA(c);
sup.methodA(c);
Limiting inheritance and overriding
If a class is declared to be final, then no
other classes can derive from it.
public final class ClassA
:Sub
:Super
This shows the inherited
Sub components of the
✔ Accessible superclass are part of
✘ Inaccessible the subclass instance
Class Hierarchy
The Effect of the Visibility Modifiers
public :Super
protected ✔ Accessible
private ✔ ✘ Inaccessible
✘
:Client ✘
:Sub
:Super
Accessibility from
✔
✘
a Client method ✘
Only public members, those defined ✔
for the class and those inherited, are ✘
visible from outside. All else is ✘
hidden from the outside.
Accessibility of Super from Sub
public
protected
private
:Sub
Accessibility from a method :Super
of the Sub class ✔
✔
✘
✔
From a method of the Sub, ✔
everything is visible except ✔
the private members of
its super class.
Accessibility from Another Instance
Data members accessible from an instance are
also accessible from other instances of the same
class.
one:ClassA two:ClassA
This could be private,
✔ Protected, or public.
✔
Inheritance and Constructors
Unlike members of a superclass, constructors of
a superclass are not inherited by its subclasses.
As always, each class that does not define a
constructor is automatically given a default
constructor.
In addition, in each constructor of a derived class,
we must make a call to the constructor of the
base class by calling: super();
This must be the first statement in the constructor.
If this statement is not present, the compiler
automatically adds it as the first statement.
You may optionally call some other constructor of
the base class, e.g.: super( “some string” );
Constructors and inheritance
The constructor for each class can be used to
initialize the variables defined in that class.
For all classes, calls to the constructors are
chained all the way back to the constructor for
the Object class.
Recall that it is also possible to call another
constructor of the same class using the this
keyword.
However, this must also be the first statement of
the constructor!
A constructor cannot call another constructor of
the same class and the base class.
Constructors
Sup
Sup
public Sup(){ public Sup(){
} super();
public Sup(int i){ }
} public Sup(int i){
super();
Sup sup1, sup2; }
Sub sub1, sub2, sub3;
Sub sup1 = new Sup();
public Sub(){ sup2 = new Sup(7); Sub Added
this(‘x’); public Sub(){ by the
} sub1 = new Sub(); this(‘x’); compiler
public Sub(char c){ sub2 = new Sub(‘y’); }
… sub3 = new Sub(5); public Sub(char c){
} super();
public Sub(int i){ …
super(i); }
… public Sub(int i){
} super(i);
…
}
Super keyword
The super keyword is a call to the constructor of
the parent class.
It can also be used to call a method of the parent
class:
super.methodA();
This can be useful to call an overridden method.
Similarly, it can be used to access data members
of the parent.
super keyword example.
Sub
Sup methodA(){
methodA(){ }
} methodB(){
methodA(int i){ methodA();
} this.methodA();
super.methodA();
methodA(7);
methodA(‘x’);
}
Question
Which method is executed for each of these
calls?
Sup sup = new Sup();
Sub sub = new Sub();
int i=9; Sup
char c='c'; methodA(){
String s=“test” }
methodA(int i){
sub.methodA(); }
sub.methodA(i);
Sub
sub.methodA(s); methodA(String s){
}
sup.methodA(c); methodA(int j){
}
Polymorphism
Polymorphism allows a single variable to refer
to objects from different subclasses in the
same inheritance hierarchy
For example, if Cat and Dog are subclasses of
Pet, then the following statements are valid:
Pet myPet;
:Sub
Example
Sup
Sub sub = new Sub();
methodA(){
Sup sup; }
methodA(String[] s){
sup = sub; }
sup.methodA();
((Sub)sup).methodA();
Sub
sub = (Sub)sup;
methodA(int i){
sub.methodA(); }
methodA(){
sub.methodA(“test”); }
The instanceof Operator
The instanceof operator can help us
discover the class of an object at runtime.
The following code counts the number of
undergraduate students.
new undergradCount = 0;
for (int i = 0; i < numberOfStudents; i++) {
if ( roster[i] instanceof UndergraduateStudent ) {
undergradCount++;
}
}
Abstract Superclasses and Methods
Interface Inheritance
:LinkedList :Node
head content “test1”
iterator next
LinkedList list;
list = new LinkedList();
:Node
String s;
s = “test1”; content “test2”
List.addToHead(s); s
s = “test2”;
next
list.addToHead(s);
s = “test3”; :Node
list.addToHead(s);
content “test3”
next
Scan list
:LinkedList :Node
head content “test1”
iterator next
…
:Node
list.startScan();
s = (String) content “test2”
s
list.getCurrentItem(); next
System.out.println(s);
while(list.hasMore()){ :Node
list.moveAhead();
content “test3”
s = (String)
list.getCurrentItem(); next
System.out.println(s);
}
Deletion list
:LinkedList :Node
head content “test1”
iterator next
:Node
content “test2”
s
next
…
list.deleteFromHead(); :Node
content “test3”
next
Queue
A similar Node class can be used to
implement another data structure called a
First-In-First-out (FIFO) queue.
A FIFO queue is often used by operating
systems for processes, requests, etc.
In a FIFO queue, items are added at one
end and deleted from the other end.
For this we need to have pointers going in
both directions: Node2
The Node2 Class
class Node2 {
private Node2 next, prev;
private Object content;
:Node2
:FifoQ
next
FifoQ q; tail content “test1”
q = new FifoQ(); head prev
String s;
s = “test1”; :Node2
q.addToQ(s); next
s = “test2”; content “test2” s
q.addToQ(s); prev
while(!q.isEmpty())
q.deleteFromQ();
Example q
:Node2
:FifoQ
FifoQ q; next
tail content “test1”
q = new FifoQ();
head prev
String s;
s = “test1”;
:Node2
q.addToQ(s);
s = “test2”; next
content “test2”
q.addToQ(s);
prev
while(!q.isEmpty())
q.deleteFromQ();