Title: CS 1312
1CS 1312
- Introduction to
- Object Oriented Programming
- Lecture 8
- Polymorphism, Exceptions Part II
2Polymorphism
3Polymorphism
- Several subclasses may have different methods for
accomplishing the same/similar behavior - You dont care about the details when you call a
method, provided you know that the object can
perform a method with that signature - E.g. you have a simulated ecology with animals in
it (SimZoo) and want to make the animals make
noise - But animals make noise in different ways
4Polymorphism
class Animal public void makeNoise ( )
System.out.println (I am an
animal.) // of makeNoise // of
Animal class Fish extends Animal public
void makeNoise( ) System.out.println
(Glug glug gurgle gurgle) //
of makeNoise // of Fish class Bird extends
Animal public void makeNoise( )
System.out.println(Tweet tweet flap flap)
// of makeNoise // of Bird
5Polymorphism (contd)
class Dog extends Animal public void
makeNoise ( ) System.out.println(Sniff
sniff woof woof) // of makeNoise
public void bark ( )
System.out.println(Arf Arf) // of
bark // of Dog
6Polymorphism
class Driver public static void main
(String argv) Animal animalArray
new Animal3 int iIndex
animalArray0 new Bird( )
animalArray1 new Dog( ) animalArray2
new Fish( ) for (iIndex0 iIndex lt
animalArray.length iIndex)
animalArrayiIndex.makeNoise( ) // of
for // of main // of Driver Output
Tweet tweet flap flap Sniff sniff woof woof
Glug glug gurgle gurgle
All animals can makeNoise, so any member of the
array can makeNoise
7Polymorphism
- Polymorphism means taking many forms ... an
object of a given class can adapt take the
form of any of its subclasses. - Polymorphism means that the correct makeNoise( )
method will always be called. - Polymorphism is legal in the State of Georgia
- A subclass can be substituted for its
superclass, e.g., a bird for an animal. A
bird is a animal. Yes. - The reverse is not true cant substitute
superclass for a subclass, e.g., - CANNOT substitute an animal for a bird.
- An animal is a bird? No. Not
necessarily. - A single interface for multiple behaviors
Only one interface for the method call. - Multiple behaviors based on the subclass.
8Polymorphism
class Driver2 public static void
main(String argv) Animal
animalArray3 Dog d int iIndex
animalArray0 new Bird( )
animalArray1 new Dog( ) animalArray2
new Fish( ) for (10 1 lt
animalArray.length iIndex) if
(animalArrayiIndex instanceof Dog)
d (Dog) animalArrayiIndex
d.bark( ) // if // main //
Driver2
We cast before calling bark() because only dogs
can bark. So some array members cannot execute
the method
9Polymorphism
- Casting
- used here to give an object of a superclass the
form of the appropriate subclass, e.g., - if (animalArrayiIndex instanceof Dog)
-
- animalArrayiIndex.bark()
-
- would produce an error because objects of class
Animal have no method called bark. So, we
first cast what instanceof tells us is a Dog as
a Dog. - if (animalArrayiIndex instanceof Dog)
-
- d (Dog) animalArrayiIndex
- d.bark( )
-
10Casting Why?
Keyword instanceof Used to interrogate an
object to see if it is an instance of the
specified class, e.g. Is this
particular animal of class Dog?
- Question
- If Java can determine that a given Animal is or
is nota Dog (via instanceof), then - Why the need to cast it to a Dog object before
Java can recognize that it can bark? - Why cant Java do it for us?
11Casting Why?
Answer difference between compile-time and
run-time type checking.
Sourcecode
Compile
Bytecode
JVMInterpreter
Programruns
errors
errors
- Run-time Errors
- Those that are discernable only when the
program is running with actual data values. - Question of execution legality
- Is it legal for this variable to have the
actual value assigned to it?, e.g.,
- animalArrayltbadIndexgt someAnimal
- Statement is legal, but particular
index value isnt.
- Compile-time Errors
- Those that are discernable without the
program executing. - Question of language legality Is this a
legal statement? e.g., - iIndex strName Statement is not
legal.
12Casting Why?
if (animalArrayiIndex instanceof
Dog) animalArrayiIndex.bark()
if (animalArrayiIndex instanceof
Dog) d (Dog) animalArrayiIndex
d.bark( )
- 1st line is legal.
- 2nd line isnt (unless array has Dog).
- We can see that 1st line guarantees 2nd is
legal. - Compiler cannot see inter-statement
dependencies unless compiler runs whole
program with all possible data sets! - Runtime system could tell easily. . . BUT. . .
We want most checking at compile-time for
reasons of bothperformance and correctness.
- Here, legality of each line of code can be
evaluated at compile time. - Legality of each line discernable without
worrying about inter-statement dependencies,
i.e., each line can stand by itself. - Can be sure that code is legal (not
sometimes-legal).A Good Use for Casting - Resolving polymorphic ambiguities for the
compiler.
13How Objects Are Created
Dog d new Dog()
1.
2.
3.
Execution Time
An implicit super() calls parent class
constructor first. After all, a Dog is-a Animal,
is-a Object
14Polymorphism...
Animal a new Dog()
We can create new references that point to
different types in the same block of memory.
Animal a new Dog() Object o a
In some sense, casting is a type of polymorphic
behavior.
15Dynamic Binding
When calling a method on an reference, the method
must be present in the type (or inherited).
However, the specific implementation called is
determined at runtime. Thats dynamic binding.
.toString()
.toString()
.toString()
System.out.println (o.toString())
Dynamic binding provides runtime resolution to
the most specific implementation possible.
16Casting and Polymorphism
Dynamic binding does not work miracles. The
reference type must have the method available (in
the present class or inherited), or else a
compilation error occurs.
o.doYourThing() // ERROR!
The calling type must have the method, either
in its instance, or from its parent.
17Questions?
18Abstract Methods Classes
19An Abstract Class
- A class like Animal is intended as a collector of
common characteristics - We want to refer to methods like makeNoise()
polymorphically - However, we have no idea how a generic animal
really makes noise. - In the example above, we used some meaningless
surrogate code - public void makeNoise ( )
- System.out.println
- (I am an animal.)
- // of makeNoise
20An Abstract Class
- We could just give up and use an empty method
like - public void makeNoise ( )
- / To be defined later /
-
- This, of course, does nothing, and we depend on
child classes to implement these methods - A software engineering tool that has been
implemented in Java is the keyword abstract - We can define the move method to be abstract
- abstract public void makeNoise()
- // Note No body!!!
- Java will then require us to designate the class
as being abstract - abstract public class animal...
21An Abstract Class
- Subclasses of abstract classes must be either
- abstract if they do not define all abstract
methods with valid method bodies - concrete
Note Cannot instantiate objects of abstract
classes!!!
abstract class animal abstract void
makeNoise()
abstract class fourLegged
class Dog void makeNoise() // Code here!
class Man void makeNoise() // Code here!
22An Abstract Class
- Using this technique Java can guarantee that all
objects that come from classes that are in the
animal class inheritance tree will have a
makeNoise method - This means that we can cast an object to be of
type animal and invoke the makeNoise method and
Java won't complain! - Object o
- o getReferenceFromSomeContainerClass()
- ((animal)o).makeNoise()
23Questions?
24Interfaces
25Multiple Inheritance
Some languages allow multiple inheritance
Animal
Pet
Two parent classes, one child class
Dog
- Multiple inheritance leads to many potentially
confusing naming problems (e.g. Pet.doYourThing()
vs. Animal.doYourThing()) - Growing consensus the benefits of multiple
inheritance arent worth the problems. - Java has single inheritance only.
- Java doesnt allow multiple inheritance
- Java does allow a construct that provides much
of the functionality of multiple inheritance The
Interface
26Interfaces Defined
- The ultimate abstract class - contains nothing
but constants and abstract method prototypes - A class is said to implement an interface if it
provides suitable real methods for all of the
abstract (virtual) methods of the interface - the class implementing that interface then
behaves as if it were inheriting from a parent
class, with one huge advantage - Since you implement all of the abstract methods
yourself, there is no other hidden, inherited
stuff to collide with - You can therefore implement as many interfaces as
you wish with no fear of the problems of multiple
inheritance
27Example
- We want a container class that can order or sort
the items it contains. - How can we compare two objects?
- We make a kind of specification
- We promise that any object we want to store in
this sorting container class will have a method
allowing it to be compared to other objects. - How do we formalize this?
- Use of an interface
28Comparable
- public abstract interface Comparable
-
- abstract int compareTo(Object o)
29Suppose...
- We want to store Box objects and for our purposes
we decide to compare boxes based on their volume. - We modify our Box class thusly
30Suppose...
- public class Box implements Comparable
- ... // Same as before including getVolume method
- public int compareTo(Object o)
- int retval -1
- if(o instanceOf Box)
- retVal getVolume() - ((Box)o).getVolume()
- if(retVal 0)
- retVal 0
- else if(retVal gt 0)
- retVal 1
- else
- retval -1
-
- return retval
-
31Running the code...
- Called like this
- Box a new Box(10, 20, 30)
- Box b new Box(2, 4, 6)
- Box c new Box(20, 10, 30)
- System.out.println(a.compareTo(b)) gt 1
- System.out.println(a.compareTo(c)) gt 0
- System.out.println(b.compareTo(c)) gt -1
- System.out.println(a.compareTo("Hello")) gt
-1
32Don't be nervous!
- If we specify that something must be Comparable
it's like saying - It must be an object (and it must implement the
compareTo method). - Its just like making a contractual obligation to
provide that method.
33Another use!!!
- Slick way to provide constants
34We can create a class just for constants
- class Constants
-
- public final static final int FEETPERMILE
5280 - public final static String PROMPT "Enter a
number" - public final static double PI 3.141592
-
- We use like this
- feet miles Constants.FEETPERMILE
35If instead we say
- Interface Constants
-
- public final static final int FEETPERMILE
5280 - public final static String PROMPT "Enter a
number" - public final static double PI 3.141592
-
- We use like this
- class Box implements Constants
- ...
- feet miles FEETPERMILE
36Questions?
37Visibility and Access
Can a given object access a field or call a
method?
Visibility Modifier Access by
public protected
private Every class Yes
No No A
subclass Yes
Yes No An
instance of the class Yes
Yes Yes
Always specify a visibility modifier.
Guidelines Only make public methods that are in
the classs contract Make all fields
private Make all other private methods
protected Dont leave off the modifier unless
you know about packages Avoid protected
members in cs1312 it has to do with
packages (not covered in cs1312)
38Questions?
39Exceptions
40What you need to know
- Last time
- What happens when an exception is thrown
- What are your choices for handling exceptions
- The different kinds of exceptions
- Today
- How to write your own exceptions
- Details of the exception classes
- Why and when you should use exceptions
- Some typical scenarios
41Two Main Ideas
Last Time
Handling Exceptions Thrown by Someone
Today
Throwing Exceptions Writing your own Exceptions
42The different kinds of exceptions
- Error
- For the big guys
- Exception
- The standard exception
- Java enforces handling
- An unusual condition
- RuntimeException
- e.g. classCast Exception
- Can indicate using a class improperly
- No special handling
43Details of the classes
Object
Error
Exception
RuntimeException
44Why and when you should use exceptions
- If the method encounters a situation it cant
handle throw an exception - Avoid using exceptions to indicate normal
operations - Use Design by Contract!
- If a client calling a method has not fulfilled
the contract throw a RuntimeException. - If your method is unable to fulfill its contract,
throw either an Exception or RuntimeException. - If you are throwing an exception for an abnormal
condition that you feel client programmers should
consciously decide how to handle, throw an
Exception.
45How to write your own exceptions
- Make a subclass of
- Exception
- Any existing exception
- Give it a name that represents what it is
- class QueueEmptyException extends Exception
- Build in extra functionality (if desired)
- You might want to do this just to give it a name
of your choosing - You might want to do this to add extra
functionality like a static counter.
46Scenarios
- You are writing a collection class and you are
wondering how to handle the condition where the
collection is empty but the bone-headed user
forgot to check. - The demons running CS1312 have decided that you
need to write your own exception or theyll make
you take the course over and over and over... - You would like to see a fairly complex yet
crystal clear example of exception usage - Might be you if its late enough!
47You are writing a collection class and you are
wondering how to handle the condition where the
collection is empty but the bone-headed user
forgot to check.
- // class Queue (continued)
- public Object dequeue() throws Exception
-
- if(isEmpty())
- throw new Exception
- (Should check isEmpty()
- before dequeueing)
- else
- // return the front object
- // ...
Note Were just throwing a plain old Exception
48The demons running CS1312 have decided that you
need to write your own exception or theyll make
you take the course over and over and over...
- class QueueEmptyException extends Exception
-
- public QueueEmptyException()
- public QueueEmptyException(String message)
-
- super(message)
-
This should go in its own file QueueEmptyExceptio
n.java
49Now we can use our own exception
- // class Queue (continued)
- public Object dequeue() throws
QueueEmptyException -
- if(isEmpty())
- throw new QueueEmptyException
- (Should check isEmpty()
- before dequeueing)
- else
- // return the front object
- // ...
50How do you use this queue?
- do
-
- try
-
- element myQueue.dequeue()
-
- catch(QueueEmptyException qee)
-
- System.out.println(This cant be happening!)
- System.out.println(qee.getMessage())
-
- while(! myQueue.isEmpty())
51Note You could choose to make this a
RuntimeException
- class QueueEmptyException extends
RuntimeException -
- public QueueEmptyException()
- public QueueEmptyException(String message)
-
- super(message)
-
52In which case...
- // class Queue (continued)
- public Object dequeue() throws
QueueEmptyException -
- if(isEmpty())
- throw new QueueEmptyException
- (Should check isEmpty()
- before dequeueing)
- else
- // return the front object
- // ...
53How do you use this queue?
- while(! myQueue.isEmpty())
-
- element myQueue.dequeue()
- .
- .
- .
If an exception is thrown, the program will
terminate.
54You would like to see fairly complex yet crystal
clear examples of exception usage
- public int getAge(int iSSN)
- throws RecordKeepingException
-
- int index getHashKey(iSSN)
- int iAge myArrayindex.getAge(iSSN)
-
- if (iAge lt 0)
- throw new RecordKeepingException
- (Exception Age for iSSN
- not in range iAge)
- else
- return iAge
-
Home-grown!
55You would like to see fairly complex yet crystal
clear examples of exception usage
- public TreeNode getNodeRecursively(int index,
TreeNode currentNode) throws MissingNodeException -
- if (currentNode null)
- throw new MissingNodeException() // Node not
found! - else if (currentNode.getNumber() index)
- return currentNode
- else if (currentNode.getNumber() gt index)
- return getNodeRecursively
- (index, currentNode.getLeftChild())
- else
- return getNodeRecursively
- (index, currentNode.getRightChild())
- // getNodeRecursively
56You would like to see fairly complex yet crystal
clear examples of exception usage
- public void initializeTreeNode(int iNumberNodes)
-
- if (myTree null)
- throw new NullPointerException
- (Null tree found)
- / NOTE Runtime exception no need to declare
propagation / - else
- for (int i0 i lt iNumberNodes i)
-
- TreeNode newNode new TreeNode( i )
- myTree.insertNode(newNode)
-
- // initializeTreeNode
57Lost Exceptions!
- class VeryImportantException extends Exception
-
- public String toString()
-
- return "A very important exception!"
-
-
- class HoHumException extends Exception
-
- public String toString()
-
- return "A trivial exception"
-
58Lost Exceptions!
- public class LostMessage
-
- void f() throws VeryImportantException
-
- throw new VeryImportantException()
-
-
- void dispose() throws HoHumException
-
- throw new HoHumException()
-
59Lost Exceptions!
- // Still in class LostMessage
- public static void main(String args)
- throws Exception
-
- LostMessage lm new LostMessage()
- try
-
- lm.f()
-
- finally
-
- lm.dispose()
-
-
60Lost Exceptions!
- The output is
- A trivial exception
- at LostMessage.dispose(LostMessage.java21)
- at LostMessage.main(LostMessage.java29)
61When Catching Exceptions you can . . .
- Print an error message
- Log the exception
- Retry the method(maybe with default parameters)
- Restore the system to some previouslyknown
"good" state. - Set the system to some "safe" state.
- Let exception propagate to whoever called the
method in which the exception arose - Catch it and ignore it
- Catch it and ignore it is generally bad If
the error was serious enough to throw an
exception, it should be dealt with, not ignored.
OOA/OOD/OOP Who knows enough to handle the
exception?
62Be sure to
- Not overuse exceptions
- Dont use to indicate normal operations
- Not underuse exceptions
- Design by Contract
- Dont ignore
- Catch exceptions
- Throw exceptions (Dont have to!)
- Write your own exceptions (Dont have to!)
63Questions?
64(No Transcript)