Download Unit 8 - CS

Document related concepts
no text concepts found
Transcript
Advance concepts in OOP

We discuss fundamental object-oriented
techniques that supports re-use of software:
• Interface and polymorphhism
• Inheritance
• Method overriding
• Polymorphism, widening & narrowing
• protected and final modifiers
syllabus
basic
programming
concepts
object oriented
programming
topics in
computer
science
1
unit 8
Principles of object-oriented programming

encapsulation: data is protected from “external”
users

inheritance: properties and methods defined for a
certain structures can be used by all structures
defined as direct offspring

polymorphism: the same function call may
invoke different code, depending on context
2
unit 8
Interfaces

A Java interface is a collection of abstract methods and
constants

An abstract method is a method header without a method
body
An abstract method can be declared using the modifier
abstract, but because all methods in an interface are
abstract, it is usually left off

An interface is used to formally define a set of methods
that a class will implement
3
unit 8
Interface: example
interface is a reserved word
public interface Doable
{
public void doThis();
None of the methods in an
interface are given
a definition (body)
public int doThat();
public void doThis2 (float value, char ch);
public boolean doTheOther (int num);
}
A semicolon immediately
follows each method header
4
unit 8
Interfaces

An interface cannot be instantiated

Methods in an interface are always public and abstract

Constant in an interface are always public, static and final

A class formally implements an interface by
• stating so in the class header
• providing implementations for each abstract method in the interface

If a class declares that it implements an interface, it must define all
methods in the interface or the compiler will produce errors
5
unit 8
Implementing interface: example
public class CanDo implements Doable
{
public void doThis ()
implements is a
{
reserved word
// whatever
}
public void doThat ()
{
// whatever
}
Each method listed
in Doable is
given a definition
// etc.
}
6
unit 8
Interfaces

A class that implements an interface can
implement other methods as well

A class can implement multiple interfaces; the
interfaces are listed in the implements clause,
separated by commas

The class must implement all methods in all
interfaces listed in the header
7
unit 8
Polymorphism via Interfaces

An interface name can be used as the type of an object
reference variable
Doable obj;

The obj reference can be used to point to any object of
any class that implements the Doable interface

The version of doThis that the following line invokes
depends on the type of object that obj is referring to:
obj.doThis();
8
unit 8
Example: Animate Interface
//************************************
// Animate.java
//
// Demonstrates the declaration of an interface
//************************************
public interface Animate
{
int HIND_LIMBS_NUM = 2;
int FORE_LIMBS_NUM = 2;
public void sound ();
public void gait (String type);
}
9
unit 8
// Parrot.java
class Parrot implements Animate
{
private String word;
//---------------------------------// Establish Parrot's vocabulary
//---------------------------------public Parrot (String word)
{
this.word = word;
}
//---------------------------------// Prints this parrot's gait
//---------------------------------public void gait (String gaitType)
{
System.out.println ("Parrots " + gaitType +
" on " + HIND_LIMBS_NUM + " limbs");
}
//---------------------------------// Prints this parrot's sound.
//---------------------------------public void sound ()
{
System.out.println ("This parrot says "
+ word);
}
}
10
unit 8
// Dog.java
class Dog implements Animate
{
private String name;
private String owner;
//---------------------------------// Establish Dog's id
//---------------------------------public Dog ()
{
name = "Lassi";
owner = "John";
}
//---------------------------------// Prints this dog's sound.
//---------------------------------public void sound ()
{
System.out.println ("woof");
}
//---------------------------------// Prints this dog's gait
//---------------------------------public void gait (String gaitType)
{
System.out.println ("Dog " + name + " " +
gaitType + " on " +
(HIND_LIMBS_NUM+FORE_LIMBS_NUM) + "
limbs");
}
//---------------------------------// Prints unique contact information
//---------------------------------public void contact()
{
System.out.println ("If you find me, call " + owner);
}
}
11
unit 8
// Pets.java
class Pets
{
//----------------------------------------------------------------// Instantiates two objects using an interface reference and invokes one of the common
// methods. Then casts interface reference into a class reference to invoke its unique method
//----------------------------------------------------------------public static void main (String[] args)
{
Animate current;
current = new Parrot("hello");
current.sound();
current.gait("walk");
System.out.println("***********\n");
current = new Dog();
current.sound();
current.gait("runs");
This parrot says hello
Parrots walk on 2 limbs
woof
Dog Lassi runs on 4 limbs
If you find me, call John
((Dog) current).contact();
}
}
12
unit 8
Polymorphism via Interfaces

Interface reference is polymorphic, which can be defined
as "having many forms"

The corresponding line of code may execute different
methods at different times if the object that obj points to
changes

Note that polymorphic references must be resolved at run
time; this is called dynamic binding

Careful use of polymorphic references can lead to elegant,
robust software designs
13
unit 8
Review: Interfaces and polymorphism

A Java interface is a collection of abstract methods and
constants; an interface is used to formally define a set of
methods that a class will implement

Interface reference is polymorphic, which can be defined
as "having many forms"

The corresponding line of code may execute different
methods at different times if the object that obj points to
changes
14
unit 8
Standard Interfaces

The Java standard class library contains many interfaces
that are helpful in certain situations

The Comparable interface contains an abstract method
called compareTo, which is used to compare two objects

The String class implements Comparable which
gives us the ability to put strings in alphabetical order

The Iterator interface contains methods that allow the
user to move through a collection of objects easily
15
unit 8
Example: Sorting Objects

Integers have an inherent order, but the order of a
set of objects must be defined by the person
defining the class

We can use the Comparable interface to
develop a generic sort for a set of objects
16
unit 8
class Contact implements Comparable {
private String firstName, lastName, phone;
// Uses both last and first names to determine lexical ordering.
public int compareTo (Object other) {
int result;
if (lastName.equals(((Contact)other).lastName))
result = firstName.compareTo(((Contact)other).firstName);
else
result = lastName.compareTo(((Contact)other).lastName);
return result;
}
public String toString()
return lastName + ", " + firstName;
}
17
unit 8
public class Sorts {
public static void insertionSort (Comparable[] objects) {
for (int index = 1; index < objects.length; index++)
{
Comparable key = objects[index];
int position = index;
// shift larger values to the right
while (position > 0 && objects[position-1].compareTo(key) > 0)
{
objects[position] = objects[position-1];
position--;
}
objects[position] = key;
}
}
}
18
unit 8
class SortPhoneList {
//----------------------------------------------------------------// Creates an array of Contact objects and sorts them
//----------------------------------------------------------------public static void main (String[] args)
{
Contact[] friends = new Contact[4];
friends[0] = new Contact ("John", "Smith", "610-555-7384");
friends[1] = new Contact ("Daphna", "Weinshall", "02-555-7777");
friends[2] = new Contact ("Moshe", "Cohen", "03-222-3333");
friends[3] = new Contact ("Marsha", "Grant", "243-555-2837");
Sorts.insertionSort(friends);
for (int i=0; i<friends.length; ++i)
System.out.println(friends[i]);
}
}
19
unit 8
Unit 8





Interface and polymorphhism
Inheritance
Method overriding
Polymorphism, widening & narrowing
protected and final modifiers
20
unit 8
Inheritance

Inheritance allows us to derive a new class from an
existing one:
• The existing class is called the superclass or base-class
• The derived class is called the subclass or derived-class

Instances of the derived class inherit all the properties and
functionality (data and methods) defined in the base class

Usually, the derived class adds more functionality and
properties
21
unit 8
Example
Employee
Executive
Executive()
giveBonus(int bonus)
Employee (String name, ...
hire(double payRate)
pay()
layoff()
promote()
...
Hourly
Hourly()
addHours(int moreHours)
22
unit 8
Properties of subclass

Everything that can be done with an Employee
object can also be done with an Hourly object

An Hourly is a special kind of Employee; it has all
the functionality of an employee and some more
 The
subclass instances are more specific than the
instances of the superclass
23
unit 8
Example: the Employee class
public class Employee {
private String name;
private String address;
private double payRate;
public Employee (String name, String address)
{
this.name = name;
this.address = address;
payRate = 0;
}
public void hire (double payRate) {
this.payRate = payRate;
}
public double pay () {
return(payRate);
}
}
public void layoff () {
payRate = 0;
}
24
unit 8
Subclass: the extends Keyword
// define a special kind of employee - LEFI SHAOT
public class Hourly extends Employee {
private int hoursWorked;
public void addHours (int moreHours)
{
hoursWorked += moreHours;
}
public double pay () {
return payRate*hoursWorked;
}
}
25
unit 8
More about subclass

Derived class should normally extend the
functionality of the superclass

In certain cases, a derived class would change
some of the functionality of the superclass
26
unit 8
The hourly subclass
// define a special kind of employee - LEFI SHAOT
public class Hourly extends Employee {
private int hoursWorked;
public void addHours (int moreHours)
{
hoursWorked += moreHours;
}
extend
change
public void pay () {
return payRate*hoursWorked;
}
}
27
unit 8
Examples
Point
Pixel
Employee
Hourly
Object
File
Switch
AdjustableSwitch
RestrictedFile
28
unit 8
What is Inherited?

The subclass inherits:
• all the fields of the base class
• all the methods of the base class

The constructors of the subclass should be defined
again

Private fields and methods are inherited but
cannot be accessed directly from the code of the
subclass; they can only be accessed indirectly
29
unit 8
Switch Example
Switch




Switch()
boolean isOn()
setOn(boolean)
isOn
30
unit 8
Switch Code
// An electronic switch that can be on/off
public class Switch
{
// Records the state of the switch
private boolean isOn;
// Checks if this switch is on
public boolean isOn() {
return isOn;
}
}
// Sets the state of the switch on/off
public void setOn(boolean state) {
isOn = state;
}
31
unit 8
Special type: Adjustable Switch
an adjustable switch has
a “level of current” dial
on
off
pressing the adjustable switch
turns it on
32
unit 8
Inheriting AdjustableSwitch from Switch

Switch



AdjustableSwitch


Switch()
isOn()
setOn(boolean)
AdjustableSwitch()
setLevel(float)
getLevel()
33
unit 8
AdjustableSwitch Example
AdjustableSwitch


isOn




level

setOn(boolean)
isOn()
AdjustableSwitch()
setLevel(float)
getLevel()
34
unit 8
AdjustableSwitch Code
public class AdjustableSwitch extends Switch {
// The level of current (0-100)
private float level;
// Sets the level of current
public void setLevel(float level) {
this.level = level;
}
// Returns the level of current of the switch
public float getLevel() {
return level;
}
}
35
unit 8
Private Fields - Inherited but not Accessible

An AdjustableSwitch object has a state
variable isOn inherited from Switch

However, it cannot be accessed directly from the
code of AdjustableSwitch because it is
defined as private in Switch (it is
encapsulated)
36
unit 8
Inheritance: a Basis for Code Reusability





Fast implementation - we need not write the implementation of
AdjustableSwitch from scratch, we just implement the
additional functionality
Ease of use - if someone is already familiar with the base class, then
the derived class will be easy to understand
Less debugging - debugging is restricted to the additional
functionality
Ease of maintenance - if we need to correct/improve the
implementation of Switch, AdjustableSwitch is
automatically corrected as well
Compactness - our code is more compact and is easier to
understand
37
unit 8
Example: Changing the Base Class

Suppose that we want to add the property of
‘maximal power’ to our representation of a switch

This property is suitable in adjustable switches as
well (the inheritance supports our abstraction!)

Inheritance allows us to add this property only in
the base class; the changes will automatically take
place in the inherited class
38
unit 8
Changing the Switch Class
public class Switch {
// Records the state of the switch
private boolean isOn;
// The maximal power of this switch
private float maxPower;
// constructor
public Switch(float maxPower) {
if (maxPower > 0.0f)
this.maxPower = maxPower;
}
// Returns the maximal power of this switch
public float getMaxPower() {
return maxPower;
}
}
39
unit 8
Constructors of subclasses must
be redefined?

The constructor of Switch receives a parameter - maxPower
- and initializes the private field with the same name

We have to define a constructor for AdjustableSwitch
that receives the same parameter and initializes this field; but
this field is private, so there is no direct access to it

In general, when we invoke a constructor of a subclass, we first
have to construct the superclass “part” of the subclass; we do
this by using the super keyword
40
unit 8
AdjustableSwitch - Redefinition of Constructor
// Constructs an adjustable switch
public AdjustableSwitch(float power) {
super(power);
}
The first line of the constructor calls the constructor of the
superclass (Switch) that receives a float parameter to
initialize the state variable defined in the superclass
41
unit 8
Calling super(...)


The constructor of a derived class MUST initialize the
state of the object from the point of view of its parent class
the first line in the constructor must be a call to one of the
constructors in the superclass using super(...)

Otherwise, the compiler automatically places a call to the
empty constructor of the superclass

A later call to super(...) is not allowed because a
constructor can be invoked only once
42
unit 8
Automatic Default Construction

In the previous implementation of Switch and
AdjustableSwitch we did not include any
constructors

The compiler automatically adds an empty
(default) constructor to each of the classes

In addition, the compiler puts in the first line of
the empty constructor of AdjustableSwitch a
call to the empty constructor of Switch
43
unit 8
Automatic Default Construction
// ...in class Switch (automatically added)
public Switch() {
}
// and in class AdjustableSwitch
//(automatically added)
public AdjustableSwitch() {
super();
}
44
unit 8
Default Construction Using Other Constructors

Sometimes the programmer may wish to define a
default constructor (i.e., a constructor with no
arguments) by herself, which may call other
constructors with default arguments of her choice

If we do this in the Switch class, we need not define
any constructor in the AdjustableSwitch class
45
unit 8
Default Construction - Delegation
// Constructs a new switch.
// @param power the maximal power of the switch
public Switch(float maxPower) {
if (maxPower > 0.0f)
this.maxPower = maxPower;
}
private static final DEFAULT_POWER = 60.0f;
// Constructs a switch with default power
public Switch() {
this(DEFAULT_POWER);
}
46
unit 8
Unit 8





Interface and polymorphhism
Inheritance
Method overriding
Polymorphism, widening & narrowing
protected and final modifiers
47
unit 8
Overriding Methods

Occassionally, when we derive a class, we want to change
some of the functionality defined in the superclass

Mechanism: a sub-class can override the definition of an
inherited method in favor of its own

That is, a child can redefine a method that it inherits from
its parent; the new method must have the same signature as
the parent's method, but can have different code

The type of the object executing the method determines
which version of the method is invoked
48
unit 8
Overriding: example


File



File(String name)
isOpen()
open()
close()
getName()

RestrictedFile



RestrictedFile(String name, long key)
isLocked()
lock()
unlock(long key)
we want clients to be able to open a restricted file only if it is
unlocked; how do we do it?
49
unit 8
File Example
public class File {
// The name of the file
private String name;
// true if the file is opened
private boolean isOpen;
// Construct a file with a given name
public File(String name) {
this.name = name;
}
// Returns the name of the file
public String getName() {
return name;
}
50
unit 8
File Example
// Checks if the file is open
public boolean isOpen() {
return isOpen;
}
// Opens the file
public void open() {
// … other operations
isOpen = true;
}
// Closes the file
public void close() {
// … other operations
isOpen = false;
}
}
51
unit 8
RestrictedFile Example
// Represents a restricted file, which can be opened only
// if unlocked; in order to unlock the file, key is needed
public class RestrictedFile extends File {
// Password for unlocking the file
private long key;
// The state of the file - locked/unlocked
private boolean isLocked;
// Constructs a new restricted file
public RestrictedFile(String name, long key) {
super(name);
this.key = key;
isLocked = true;
}
52
unit 8
RestrictedFile: added methods
// Checks if the file is locked
public boolean isLocked() {
return isLocked;
}
// Locks the file
public void lock() {
isLocked = true;
}
// Unlock the file; the file will be unlocked only
// if the given key is valid
public void unlock(long key) {
if (this.key == key) {
isLocked = false;
}
}
So far the implementation is useless if we do not change the
53
implementation of open()
unit 8
Method overriding
// Open the file - file will be opened
// only if it is unlocked
public void open() {
if (!isLocked()) {
super.open();
}
}
54
unit 8
Overriding in RestrictedFile

RestrictedFile inherits the interface of
File, but changes the functionality of the method
open()

We say that RestrictedFile overrides the
method open()

Note the call to super.open() - we invoke the
method open() of the superclass on this object
55
unit 8
Rules of Inheritance

When class B is derived from a class A, the
interface of class B will be a superset of that of
class A (except for constructors)

It is not possible to remove a method from the
interface by subclassing

However, class B can override some of the
methods that it inherits and thus change their
functionality
56
unit 8
Rules of Overriding

When overriding a method, a parent method can
be explicitly invoked using the super reference

If a method is declared with the final modifier,
it cannot be overridden

The concept of overriding can be applied to data
(called shadowing variables), but there is
generally no need for it
57
unit 8
Overloading vs. Overriding

Overloading deals with
multiple methods in the
same class with the same
name but different
signatures

Overriding deals with two
methods, one in a parent
class and one in a child
class, that have the same
signature

Overloading lets you
define a similar operation
in different ways for
different input data
(different parameters)

Overriding lets you define
a similar operation in
different ways for
different object types
58
unit 8
Unit 8





Interface and polymorphhism
Inheritance
Method overriding
Polymorphism, widening & narrowing
protected and final modifiers
59
unit 8
Class Hierarchies

A child class of one parent can be the parent of
another child, forming class hierarchies
StaffMember
Employee
Hourly
Executive
Volunteer
Sherut Leumi
60
unit 8
Class Hierarchies

Two children of the same parent are called siblings

Good class design puts all common features as
high in the hierarchy as is reasonable

An inherited member is continually passed down
the line

Class hierarchies often have to be extended and
modified to keep up with changing needs
61
unit 8
The Object Class

A class called Object is defined in the java.lang
package of the Java standard class library

All classes are derived from the Object class

If a class is not explicitly defined to be the child of an
existing class, it is assumed to be the child of the
Object class

The Object class is therefore the ultimate root of all
class hierarchies
62
unit 8
The Object Class

The Object class contains a few useful methods,
which are inherited by all classes

For example, the equals method of the Object
class determines if two references are aliases

When you define a new class, you can override
equals to define equality in some other way
63
unit 8
The Object Class

The toString method is defined in the Object class: it
returns a string that contains the name of the object’s class and a
hash value

That’s why the println method can call toString for any
object that is passed to it – all objects are guaranteed to have a
toString method via inheritance

When we define a new class, we can override the toString()
method in order to have a suitable representation of the new type
of objects as Strings
64
unit 8
Example of Overriding toString()
// Represents a point on a grid
public class Point {
// The coordinates of the point
private int x,y;
// Constructs a new point
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return “(“ + x + ”,” + y + ”)”;
}
65
unit 8
Example of Overriding toString()
// Example: overriding the toString() method
class PrintingPointExample {
public static void main(String[] args) {
Point p = new Point(2,3);
System.out.println(p);
//System.out.println(p.toString());
}
}
66
unit 8
Class Hierarchy: example
a RestrictedFile is-a File which is-a Object
Object
File
RestrictedFile
67
unit 8
Reference and Inheritance

We can view a RestrictedFile object from 3 different points
of views:
• As a RestrictedFile: this is the most narrow point of view
(the most specific); this point of view ‘sees’ the full functionality of
the object
• As a File: this is a wider point of view (a less specific one); this
point of view is ‘ignorant’ of the special characteristics the object
has as a RestrictedFile (we can only open and close the file)
• As an plain Object
68
unit 8
1 Object reference, many types

We view an object by using an object reference

A variable of type ‘reference to File’ can only refer to an
object which is a File:
File f = new File(“story.txt”);

But a RestrictedFile is also a File, so f can also refer
to a RestrictedFile object:
File f = new RestrictedFile(“visa.dat”);

The type of the reference we use determines the point of view
we will have on the object
69
unit 8
Point of View 1
If we refer to a RestrictedFile object using a
RestrictedFile reference, we have the
RestrictedFile point of view - we see all the methods that
are defined in RestrictedFile and up the hierarchy:





RestrictedFile f =
new RestrictedFile(“visa.dat”, 12345);
f.close();
f.lock();
f.unlock(12345);
String s = f.toString();
70
unit 8
Point of View 2
If we refer to a RestrictedFile object using a
File reference, we have the File point of view – we
see only methods that are defined in class File and up
the hierarchy tree:





File f =
new RestrictedFile((“visa.dat”, 12345);
f.close();
f.lock();
f.unlock(12345);
String s = f.toString();
71
unit 8
Point of View 3
If we refer to a RestrictedFile object using an
Object reference, we have the Object point of view
- we see only methods that are defined in class
Object:





Object f =
new RestrictedFile((“visa.dat”, 12345);
f.close();
f.lock();
f.unlock(12345);
String s = f.toString();
72
unit 8
Visualization
RestrictedFile





...
isOpen
isLocked
key







toString()
...
isOpen()
open()
close()
lock()
unlock(key)
isLocked()
object
file
restricted file
73
unit 8
References and Inheritance

An object reference can refer to an object of its class, or to an
object of any descendant class related to it by inheritance

Assigning a child object to an ancestral reference is
considered to be a widening conversion, and can be
performed by simple assignment

Assigning an object with ancestral reference to a child
reference can also be done, but it is considered to be a
narrowing conversion and must be done with an explicit cast
74
unit 8
Widening

Changing our point of view of an object to a wider one
(a less specific one) is called widening:
File file;
file = new RestrictedFile((“visa”, 1234);
File reference
File point of view
RestrictedFile reference
RestrictedFile point of view
Widening
75
unit 8
Point class example
// A point on a grid
public class Point {
// ... The same implementation as before
// Computes the distance from another point
// @param p: the given point
public double distanceFrom(Point p) {
int dx = x-p.x;
int dy = y-p.y;
return Math.sqrt(dx*dx+dy*dy);
}
// ... more methods
}
76
unit 8
Pixel subclass example
// Represents a pixel on a graphical area
public class Pixel extends Point {
// The color of the pixel
private Color color;
// Constructs a new pixel
public Pixel(int x, int y, Color color) {
super(x,y);
this.color = color;
}
// ... more methods
}
77
unit 8
Widening

In the following example, the method
distanceFrom() expects a ‘reference to Point’
and gets ‘a reference to Pixel’; we are thus
widening our point of view of the Pixel object
Pixel p1, p2;
p1 = new Pixel(2, 3, Color.yellow);
p2 = new Pixel(5, 6, Color.red);
double d = p1.distanceFrom(p2);
78
unit 8
Narrowing

If we look at all objects from a wide point of view,
and would not be able to restore a more narrow
view for some of them, there is little point in
having multiple points of view

We can restore the narrow point of view for
objects by casting

We can use the instanceof operator to query
about the type of the object we are referencing
79
unit 8
Narrowing Example
// Locks all the restricted files in the array
// @param files: the array of files to be locked
public static void lockRestrictedFiles(File[] files) {
for (int i = 0; i < files.length; i++) {
if (files[i] instanceof RestrictedFile) {
RestrictedFile file = (RestrictedFile)files[i];
file.lock();
}
}
}
RestrictedFile point of view
File point of view
Narrowing
80
unit 8
Narrowing - Equivalent Example
// Locks all the protected files in the array
// @param files The array of files to be locked
public static void lockRestrictedFiles(File[]
files) {
for (int i = 0; i < files.length; i++) {
if (files[i] instanceof RestrictedFile) {
((RestrictedFile)files[i]).lock();
}
}
}
81
unit 8
Rules of Narrowing

Narrowing lets us restore a more specific point of view of
an object

You cannot refer to an object through a
RestrictedFile reference unless this object is indeed
a RestrictedFile object

If we try to cast a File reference to RestrictedFile
and the former reference refers to a regular File, we will
get the error message ClassCastException

In the previous example we cast the reference only after
we verified the object is indeed a RestrictedFile
82
unit 8
Polymorphism via Inheritance

We saw how an interface can be used to create a
polymorphic reference

Recall that a polymorphic reference is one which can refer
to different types of objects at different times

Inheritance can also be used as a basis of polymorphism

An object reference can refer to one object at one time,
then it can be changed to refer to another object (related by
inheritance) at another time
83
unit 8
Polymorphism via Inheritance: example

Suppose the Employee class has a method called pay,
and the Hourly class overrode it

Now consider the following invocation:
Daphna.pay();

If Daphna refers to a Employee object, it invokes the
Employee version of pay; if it refers to a Hourly
object, it invokes the Hourly version
84
unit 8
Polymorphism via Inheritance

It is the type of the object being referenced, not
the reference type, that determines which method
is invoked

Note that, if an invocation is in a loop, the exact
same line of code could execute different methods
at different times

Polymorphic references are therefore resolved at
run-time, not during compilation
85
unit 8
Type of Method is Determined at
Runtime (1)
File file;
if (Math.random() >= 0.5) {
file = new File();
}
else {
file = new RestrictedFile(“visa.dat”, 76543);
// Recall that a RestrictedFile is locked by
// default
}
file.open();
Will the file be opened if the number tossed is less than 0.5 ??
86
unit 8
Type of Method is Determined at
Runtime (2)
public void workaroundAttempt(RestrictedFile file) {
File workaroundReference = file;
workaroundReference.open();
//
}
Since the file is of type RestrictedFile, this will invoke open()
which is defined on restricted files and not on regular files
will the file be opened?
87
unit 8
Heterogeneous Collections

Polymorphism is especially useful when we want to
create a heterogeneous collection of objects

Example: a class Staff that represents all workers in a
certain organization, some of whom are employees and
some are volunteers

Among the employees: some are regular employees paid
monthly, some are temporary and are paid by the hour,
while some are managers (executives) and get bonuses
88
unit 8
Example: StaffMember Class Hierarchy
StaffMember
Employee
Hourly
Volunteer
Executive
89
unit 8
StaffMember class
// StaffMember.java
class StaffMember
{
private String name;
private String address;
private String phone;
// constructor
public StaffMember (String name, String address,
String phone){
this.name = name;
this.address = address;
this.phone = phone;
}
public double pay(){
return 0.0;
}
}
90
unit 8
Volunteer subclass
// Volunteer.java
class Volunteer extends StaffMember
{
// constructor
public Volunteer (String name, String address,
String phone)
{
super (name, address, phone);
}
// override method
public double pay ()
{
return 0.0;
}
}
91
unit 8
Employee subclass
// Employee.java
class Employee extends StaffMember
{
private double payRate;
// constructor
public Employee (String name, String address,
String phone, double payRate)
{
super (name, address, phone);
this.payRate = payRate;
}
// override method
public double pay ()
{
return payRate;
}
}
92
unit 8
Hourly subclass of Employee
// Hourly.java
class Hourly extends Employee
{
private int hoursWorked;
// constructor
public Hourly (String name, String address,
String phone, double payRate)
{
super (name, address, phone, payRate);
hoursWorked = 0;
}
// unique method
public void addHours (int moreHours)
{
hoursWorked += moreHours;
}
…
93
unit 8
Hourly subclass of Employee (cont)
//---------------------------------------------// override method pay of Employee: Compute
// and return the pay for this hourly employee
//--------------------------------------------public double pay ()
{
double payment = payRate * hoursWorked;
hoursWorked = 0;
return payment;
}
}
94
unit 8
Executive subclass of Employee
// Executive.java
class Executive extends Employee
{
private double bonus;
// constructor
public Executive (String name, String address,
String phone, double payRate)
{
super (name, address, phone, payRate);
bonus = 0; // bonus has yet to be awarded
}
// unique method
public void awardBonus (double execBonus)
{
bonus = execBonus;
}
…
95
unit 8
Executive subclass of Employee (cont)
//----------------------------------------------// override method pay of Employee: Compute and
// return the pay for an executive, which is the
// regular employee payment plus a one-time bonus
//----------------------------------------------public double pay ()
{
double payment = super.pay() + bonus;
bonus = 0;
return payment;
}
}
96
unit 8
Heterogeneous collections

Suppose we would like to store personnel of all
kinds in a single array, so we can easily write code
that takes care of all the workers

For example, suppose we want to implement a
method getTotalCost() in class Staff that
will compute how much money is needed to pay
all personnel at the end of the month
97
unit 8
// Staff.java
class Staff
{
StaffMember[] staffList;
‹——›
narrowing
‹——›
widening
// constructor: sets up the list of staff members.
public Staff ()
{
staffList = new StaffMember[4];
staffList[0] = new Executive (”Carla", "123 Main
Line", "555-0469", 1923.07);
staffList[1] = new Employee ("Sam", "456 Off
Line", "555-0101", 846.15);
staffList[2] = new Hourly ("Diane", "678 Fifth
Ave.", "555-0690", 8.55);
staffList[3] = new Volunteer ("Norm", "987 Suds
Blvd.", "555-8374");
((Executive)staffList[0]).awardBonus (5000.00);
((Hourly)staffList[2]).addHours (40);
}
//
compute payday costs
public void getTotalCost ()
{
double amount = 0.0;
for (int count=0; count < staffList.length; count++)
{
amount += staffList[count].pay(); // polymorphic
}
}
}
We do not care if staffList[count] refers to a
Volunteer, a regular Employee, an Hourly or an
Executive; they all “know” how to compute their pay
Unit 8





Interface and polymorphhism
Inheritance
Method overriding
Polymorphism, widening & narrowing
protected and final modifiers
100
unit 8
The protected Modifier

Any class member (variable, method or constructor) can be
declared with one of the 4 visibility modifiers:
• private - only code of the same class in which the
member has been defined can access this member
• (none) - default visibility; only code of a class of the same
package as that of the class in which the member has been
defined can access it
• protected - code in a class that is in the same package or
is a subclass of the class in which the member was defined
• public - code of any class that can access the class of that
member

We declare variables as protected if they will be used
often by someone deriving our class, but we still want to
hide them from a user of our class
101
unit 8
Class 2
Class 1
ok
int a;
ok
ok
public int b;
ok
ok
protected int c;
ok
no
private int d;
no
SubClass 1
package 1
Class 2
package 3
Class 1
no
int a;
no
ok
public int b;
ok
no
protected int c;
ok
no
private int d;
no
package 1
SubClass 1
package 2
102
unit 8
Point: Example of a protected Field
public class Point {
// The coordinates of the point
protected int x,y;
// constructor
public Point(int x, int y) {
this.x = x;
this.y = y;
}
// ...
}
103
unit 8
Protected Fields Example
public class Pixel extends Point {
// The color of the pixel
private Color color;
// constructor
public Pixel(int x, int y, Color color) {
super(x,y);
this.color = color;
}
// Draws this pixel
public void draw() {
this method will need to refer to x,y
and it will be cumbersome to do this
through access methods
}
}
104
unit 8
The final modifier
The final modifier can be used for classes, methods and
variables; in each case it has a different meaning:

A final class can not have derived classes

A final method cannot be overriden

A final variable can be initialized only once
• If the variable is static you must specify its value in the
declaration and it becomes a constant
• If it is a state variable, you should either specify a value in
the declaration or in the constructor, but only there and only
105
once
unit 8
Heterogeneous Collections in the
Java API

library class: java.util.Vector

A vector is an oredered collection of objects

You may add or remove objects from the vector at
any position

The size of a Vector grows and shrinks as needed
to accommodate adding and removing items after
the Vector has been created
106
unit 8
Heterogeneous Collections: Vector
class Cat {
public String
return new
}
}
class Dog {
public String
return new
}
}
class Mouse {
public String
return new
}
}
toString() {
String(“meaw”);
toString() {
String(“bark”);
toString() {
String(“squeak”);
107
unit 8
Heterogeneous Collections: Vector
class MouseTrap {
public static void main(String[] args) {
Vector v = new Vector();
v.addElement(new Cat());
v.addElement(new Mouse());
v.addElement(new Dog());
v.addElement(new Mouse());
v.addElement(
new String(“it’s raining cats and dogs”));
for (int i = 0; i < v.size(); i++)
System.out.println(v.elementAt(i));
catchTheMice(v);
}
108
unit 8
Heterogeneous Collections: Vector
private static catchTheMice(Vector v) {
int i = 0;
while (i < v.size())
if (v.elementAt(i) instanceof Mouse) {
v.removeElementAt(i);
}
else {
i++;
}
}
}
109
unit 8
Multiple Inheritance: Motivation

Suppose we want to add a new kind of employee –
a visitor
Employee
Executive
Visitor
But there can be visitors who are executives as well,
so what do we do in this case?
110
unit 8
Single vs. Multiple Inheritance

We would like to define a VisitingExecutive class that
extends both Executive and Visitor

Multiple inheritance allows a class to be derived from two
or more classes, inheriting the members of all parents;
collisions, such as the same variable name in two parents,
have to be resolved

Java supports single inheritance, meaning that a derived
class can have only one parent class (C++ supports
multiple inheritance)

In most cases, the use of interfaces gives us the best
aspects of multiple inheritance without the overhead
111
unit 8
Interface Hierarchies

Inheritance can be applied to interfaces as well as classes

One interface can be used as the parent of another

The child interface inherits all abstract methods of the
parent

A class implementing the child interface must define all
methods from both the parent and child interfaces

Note that class hierarchies and interface hierarchies are
distinct (the do not overlap)
112
unit 8