Title: Packages
1Introduction to Computer Science
Unit 12
- Packages
- Polymorphism
- Interfaces
- Exceptions
- Streams input/output
2Packages
- Java classes are placed into directories (or
folders) on the computer - The classes in each directory form a package
- This helps organize classes, and also gives
another way of controlling access among classes - Example java.applet is the package of classes in
subdirectory "applet" under the directory "java"
(whose location varies depending on the system)
3Sample Packages that come with the Java API
(continually evolving)
- java.applet Classes for implementing applets
- java.awt For graphics, windows, GUIs
- java.awt.event For AWT event-handling model
- java.awt.image Classes for image processing
- java.awt.peer Interface defs, platform-indep.
GUIs - java.io Classes for input and output
- java.lang Basic language classes (String,
Math) - java.net Classes for networking
- java.util Useful auxiliary classes, like Date
4Direct Use of Java API Class
- To use, for example, the class Math in the
package java.lang, it is possible to use the
fully-qualified namex java.lang.Math.sqrt(3)
5Importing Classes
- Of course, it's more convenient to do it the way
we've been doing it, using the import statement
eitherimport package_name.class_nameorimpo
rt package_name.
6Importing
- import package_name.class_nameallows
class_name to be used without giving the full
package name - import package_name.allows all classes in the
package to be used without qualifying their names
7Example of import
java.util.Date d new java.util.Date(
)java.awt.Point p new java.awt.Point(1,
2)java.awt.Button b new java.awt.Button(
)can be abbreviated asimport
java.util.Dateimport java.awt.Date d new
Date( )Point p new Point(1, 2)Button b
new Button( )
8It's Always There
- Java always assumes that the classes in java.lang
(basic language classes, such as String and Math)
are available - It's as if you have the statementimport
java.lang.at the beginning of every program
9Packages You Define
- All of the .class files placed in one directory
belong to the same, unnamed package - To cause a class to be placed in a particular
named package - Put the .class file in the appropriate directory
- Compile the class with the package statement,
which must be the first non-comment line in the
Java source filepackage package-name
10Classes in Different Packages
- Classes in different packages obviously have
different fully-qualified names - Classes in different packages also have different
rules regarding the visibility of names
11ExampleVisibility of Instance Variables
- A public instance variable is visible to all
other classes - A private instance variable is visible only to
the methods of its class - If it is declared neither public nor private,
then it has "package visibility" it is visible
to methods defined in other classes in the same
package as its class - Same rules apply to static variables and instance
and static methods
12Similarly for Classes
- A class declared public is visible to all classes
- A class not declared public is visible to the
classes in its own package - A class cannot be declared private
13private, public, protected
- Private variables and methods no access by
clients or by subclasses - Public variables and methods accessed by clients
and by subclasses - Default (no label) variables and methods have
package visibility, accessible only to clients
and subclasses in the same package
14Protected
- We might want to give subclasses access to
variables and methods without allowing clients to
have access - That's the purpose of another category of
accessibility protected - Members declared protected are visible to other
classes in the same package, and to subclasses in
other packages, but not to clients in other
packages
15Two Kinds of Visibility
- Inherited Visibility and Direct Access
Visibilityclass A int _x class B
extends A _x // inherited visibility of
x A._x // direct access visibility of x
16Summary of Visibility
Visibility public default protected private clien
ts in D D D nonesame package clients
in D none none nonedifferent
package subclass in D I D I D
I nonesame package subclass in D I none
I nonedifferent package
I inherited access, D direct access
17Using Protected
- When there's a possibility that a class will have
subclasses (and you want the attributes and
methods to be usable in the inheritance
hierarchy), you should use protected - Inherited protected variables and methods are
considered to be protected members of the
subclass (visible to further subclasses, and
hidden from clients) - Inherited public variables and methods are
considered to be public members of the subclass
(visible to everyone)
18class PreciseTime extends Time public void
printTime ( ) if ((_hour 0)
(_minute 0)) System.out.print(midnight)
else if ((_hour 12) (_minute
0)) System.out.print(noon) else
if (_hour 0) System.out.print(12) els
e if (_hour gt 12) System.out.print(_hour -
12) else System.out.print(_hour) if
(_minute lt 10) System.out.print(0
_minute) else System.out.print(
_minute) if (_second lt 10) System.out.print(
0 _second) else System.out.print(
_second) if (_hour lt 12) System.out.print(
AM) else System.out.print(PM)
Now we overrideprintTime( )
19Doesn't Work
- Problem is, it doesn't work the new printTime
accesses _hour and _minute, private instance
variables of class Time - So we need to change the definition of class
Time class Time protected int _hour,
_minute - Still no access to _hour and _minute from regular
clients of Time, just to PreciseTime and other
subclasses of Time
20Constructors for Subclasses
- Java guarantees that a classs constructor method
is called whenever an instance of that class is
created - It also guarantees that the constructor is called
whenever an instance of any subclass is created - Therefore, every constructor method must call
(explicitly or implicitly) its superclass
constructor method
21Constructors for Subclasses
- If we have an inheritance hierarchy
class Bsubclass C of Bsubclass D of
Csubclass F of subclass G of F
If a new object of class G is created, the
constructors will be called in order B, C, D, ,
F, G (i.e., G calls F, which calls E,)
22Constructor Chaining
- If the first statement in a constructor is not an
explicit call to a constructor of the superclass
(using super), or an explicit call to another
constructor in the same class (using this), then
Java implicitly inserts the call super( ) (i.e.,
super with no arguments) - Even if this is used to invoke another
constructor in the same class, eventually some
constructor will (explicitly or implicitly)
invoke the superclass constructor - If the superclass has no zero-argument
constructor, the implicit super( ) causes a
compilation error
23super( )
- Therefore, if a superclass doesn't have a
zero-argument constructor, the subclass must
explicitly call the superclass's constructor with
argumentsclass C extends B public C ()
super( B's constructor arguments )
24super( )
- The call to super() must be the first statement
in the body of C's constructor - The constructor for PreciseTime made use of this
feature, calling super(h, m) to allow the Time
constructor to do initialization
public PreciseTime(int h, int m, int s)
super(h, m) _second s
25Dynamic Binding
- I said that a PreciseTime object is also (kind
of) a Time object - It's a useful way of thinking about it, and it is
the basis for a very powerful feature of Java,
dynamic binding - A PreciseTime object can be used almost anywhere
that a Time object can be used
26Several Passes at Polymorphism
- Polymorphism means taking many forms a
reference of a given class can adapt take the
form of any of its subclasses. - First we will look at the polymorphism and
dynamic binding quickly a few key facts - Then we will look at it in depth this set of
slides adapted (with permission)
fromwww.cc.gatech.edu/classes/AY2002/cs1322_spri
ng/slides/ current/CS2_22_PolymorphismDynamicBindi
ng.ppt
27This is legal, blurring the distinction of Time
and PreciseTime
Time dawn dawn new PreciseTime(3, 45, 30)
- A Time variable (like dawn) can contain a
reference to a PreciseTime object - More generally, a CCC variable can contain a
reference to any object of any class in CCC's
subclass hierarchy (down the tree but not up
the tree)
28There's an order to this
dawn
heap
29This is legal, blurring the distinction of Time
and PreciseTime
- Time dawn
- dawn new PreciseTime(3, 45, 30)
dawn
Attributes _hour 3 _minute 45
_second 30Methods
dawn
heap
30So now what?
- What happens if we send dawn the printTime( )
message?dawn.printTime( )printTime( ) is
defined in both Time and PreciseTime classes - dawn was declared as a Time variable, but the
actual object in dawn is a PreciseTime object - So the printTime( ) defined in the PreciseTime
class will be used
31Static Binding of Methods
- Before we had subclasses, life was simple
- The Java compiler could always figure out,
without running the program, which instance
method would be invoked - The ability to know the exact method that will be
invoked every time a message is sent is called
static binding of methods
32Dynamic Binding
- This is no longer true when we have subclasses
- It is possible to specify in a program that
there's an object of some class, B (i.e., the
object is defined as being referenced by a
variable of type B) - B has subclasses C and D
- C and D each provide their own definition of
method f ( )
B newObj
B
C
D
33Dynamic Binding
- The actual creation of the object (C or D) only
occursat runtime - Therefore, the compilercan't know, when the
object newObj is sent f ( ), whether it will be
handled by the C definition or the D definition
we can only know at runtime
x might come from the user
if (x 7) newObj new C( )else newObj
new D( )
newObj.f( )
Using f( ) from class C or D?
34Polymorphism Pass 2More In Depth
- Polymorphism is an important concept that is a
part of Object Oriented Programming - We often would like to deal with a collection of
various types of objects. We want to process
members of that group in a generic way. Yet in
the end, wed like specific and appropriate
behavior to still occur. - This set of slides adapted (with permission)
fromwww.cc.gatech.edu/classes/AY2002/cs1322_spri
ng/slides/current/ CS2_22_PolymorphismDynamicBindi
ng.ppt
35Polymorphism
- Example We have an array of animals, each of
which is an object of one subclass out of several
possible subclasses of Animal. The array is
declared to have Animal as its element type.
Now wed like to process through the array and
have each element invoke a makeNoise() method. - Luckily when a method call is made, the compiler
isnt too concerned about the specifics of the
method being called. Its question is is
there a method with a matching signature?
36Array of Animals
Animal
extends
extends
extends
Fish
Bird
Dog
- Fill an array with Bird, Dog, Fish but the
array is an array of Animal
An array of Animal we want to fill it with
different instances of animals, but send the same
message to each they each will respond
differently
0
1
2
37Polymorphism
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
38Polymorphism (contd)
class Dog extends Animal public void
makeNoise( ) System.out.println("Sniff
sniff woof woof") // of makeNoise
public void bark( ) System.out.println("Ar
f Arf") // of bark // of Dog
39Polymorphism
public class Driver public static void main
(String argv) Animal animalArray
new Animal3 int index
animalArray0 new Bird( )
animalArray1 new Dog( ) animalArray2
new Fish( ) for (index 0 index
lt animalArray.length index)
animalArrayindex.makeNoise( ) // of
for // of main // of Driver
Output Tweet tweet flap flap Sniff sniff
woof woof Glug glug gurgle gurgle
the Animal class has makeNoise, so any member of
the array can makeNoise
40Polymorphism and Dynamic Binding
- Polymorphism Dynamic Binding together insure
that the correct makeNoise( ) method will always
be called. - An object of 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.
41instanceof
- The keyword instanceof is used to ask an object
if it is an instance of the specified class,
e.g., "Is this particular animal of class Dog?"
(d instanceof Dog)
- Its a boolean relation, returning true or false
if (d instanceof Dog)
42Casting with Polymorphism
public class Driver2 public static void
main(String argv) Animal
animalArray3 Dog d int i
animalArray0 new Bird( )
animalArray1 new Dog( ) animalArray2
new Fish( ) for (i 0 i lt
animalArray.length i) if
(animalArrayi instanceof Dog) d (Dog)
animalArrayi d.bark( )
// if // main // Driver2
We cast before calling bark() because only dogs
can bark. Not all Animals can execute the method
43Upcasting
- Why didnt we have to explicitly cast Bird, Dog
and Fish to Animal when we put the instances into
the array on the previous slide? - Because this is upcasting casting from a
derived class to a base class and Java does it
for us automatically - You can also write it explicitly if you want (no
harm done)
44Casting a Superclass to a Subclass
- Casting used here to give an object of a
superclass the form of the appropriate subclass.
If we just wrote
if (animalArrayi instanceof Dog)
animalArrayi.bark()
it would produce an error because objects of
class Animal have no method called bark. So, we
first cast the object that instanceof tells us is
indeed a Dog object, as a Dog.
if (animalArrayi instanceof Dog) d (Dog)
animalArrayi d.bark( )
45Why is Casting Necessary Here?
- If Java can determine that a given Animal is or
is not a Dog (via instanceof), then why do we
need to cast it to a Dog object before Java can
recognize that it can bark? - Why cant Java do it for us automatically?
- Answer the difference between compile-time and
run-time type checking.
46Why is Casting Necessary Here?
Sourcecode
Compile
Bytecode
JVMInterpreter
Programruns
errors
errors
- Compile-time Errors
- Those that are discernable without the
program executing. - Question of language legality "Is this a
legal statement?" e.g., - index strName Statement is not
legal.
- 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 legal, but particular index value isnt.
47Why is Casting Necessary Here?
if (animalArrayi instanceof Dog)
d (Dog) animalArrayi d.bark( )
if (animalArrayi instanceof Dog)
animalArrayi.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.
48How Objects Are Created
Dog d new Dog()
1.
2.
3.
Object
Object
Object
Animal
Animal
Animal
Dog
Dog
Dog
d
d
d
Execution Time
An implicit super() calls parent class
constructor first. After all, a Dog is-a Animal,
is-a Object
49Multiple References to Different Types of the
Same Instance
We can create new references that point to
different types in the same block of memory.
Animal a new Dog() Object o a
50Dynamic Binding
When calling a method on a 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.
51Casting 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.
52What Should Our Array Elements Be?
So, we have these three blocks, representing
objects in memory, each different, holding unique
references and primitive values. How can these
disparate objects be held in an array, which must
be heterogeneous?
The organizing principle is the shared inherited
relationship with Animal. Since Fish, Dog and
Bird all extend from Animal, we can make an
Animal array to hold different expressions of
this class.
53What Should Our Array Elements Be?
So, we have these three blocks, representing
objects in memory, each different, holding unique
references and primitive values. How can these
disparate objects be held in an array, which must
be heterogeneous?
We could also have made an array of Object types.
But we then will have problems invoking methods
on members of this array, since Object lacks key
methods--like move().
54What Should Our Array Elements Be?
So, we have these three blocks, representing
objects in memory, each different, holding unique
references and primitive values. How can these
disparate objects be held in an array, which must
be heterogeneous?
So we select Animal as our common type. Its the
most specific type, and yet is still held in
common by all the members we plan to hold in the
array.
55Multiple References to Instance
Bird bTemp new Bird() Object oTemp (Object)
bTemp Animal aTemp (Animal) bTemp
Here, the casting is not needed since we
are upcasting. Its shown to be explicit.
aTemp
bTemp
oTemp
Recall that we can have many reference types
pointing to the same Fish or Dog or Bird instance
in memory. Thus, since arrays must be of a
single type, we just polymorph any references we
have into Animal references.
56Array Elements are of a Single Type
Object
Thus, when we have many objects in memory, we
polymorph our references to the instances. This
gives us an array of Animal types, even though
each instance is a different subclass.
toString()
Animal
final int length 3
1
2
0
Lets invoke some methods on these objects.
57Is our picture correct?
What if we executed this code
Object oTemp oTemp animalArray1
Object
oTemp
58Is our picture correct?
What if we executed this code
Object oTemp oTemp animalArray1
oTemp
59Does this work?
Now, lets add another line of code
Object oTemp oTemp animalArray1 oTemp.move()
oTemp
NO. The class Object has no method called
move()
60The fix is in
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp
oTemp
aTemp
Note the explicit down casting was necessary.
61The fix is in
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp aTemp.move()
oTemp
aTemp
Hmm... Lets look at this closely.
62Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp aTemp.move()
oTemp
aTemp
The reference type we are using is an Animal
type. Would that determine whether Animal or
Fish has their method called?
It looks like both Animal and Fish have move( )
methods.
Which one gets called when the aTemp.move( ) line
executes?
NEVER.
63Dynamic Binding
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp aTemp.move()
aTemp
Understand this term.Understand what is does.It
is a CORE feature of any Object Oriented
language.
Here, the principle of dynamic binding will
ensure that at run time, the most specific
behavior will be invoked. Here, the Fish move()
method is more specific than its parent method.
So, the Fishs move() method gets called with the
aTemp.move() line.
64Sanity Check
oTemp
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp System.out.println
(oTemp.toString())
Does casting somehow overpower dynamic binding?
NEVER.
What Happens Here?
What about System.out.println (
((Object)oTemp).toString() )
65Sanity Check
oTemp
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp System.out.println
(oTemp.toString())
No matter how you cast things, dynamic binding
takes hold. Its like the law of gravity.
What Happens Here?
What about
System.out.println ( ((Object)oTemp).toString( )
)
66Sanity Check
oTemp
Object oTemp oTemp animalArray1 Animal
aTemp (Animal) oTemp System.out.println
(oTemp.toString())
No matter how you cast things, dynamic binding
takes hold. Its like the law of gravity.
What if Fish had its own toString()?
Dynamic binding will always resolve, at run time,
to the most specific version of the method.
ALWAYS.
67Always?
Object oTemp oTemp animalArray1 oTemp.move()
// WRONG!
oTemp
No such method move() in Object
Does dynamic binding also work miracles? That
is, does it let you find methods in extending
classes, if the present class does not have such
a method?
NO. This would cause a compile time error. Java
is strongly typed, meaning that each time you
invoke a method, the method MUST be present in
the class--even if dynamic binding would later
find a more specific version. So no, dynamic
binding does not defeat type safety in Java.
68Another example A Hierarchy Diagram
Has method (among others)public String
toString()
Object
Has methodspublic boolean isOpen() public void
open() public void close() public String getName()
File
Has methodspublic boolean isLocked() public
void lock() public void unlock(long
key) Redefines open() (only open file if it is
unlocked its locked at creation)
RestrictedFile
69Sub-classes as Sub-types
- 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). We forget about the special
characteristics the object has as a
RestrictedFile (we can only open and close the
file). - As a plain Object.
70Variables can Reference Sub-class Values
- We view an object by using an object reference.
- A variable of type reference to File can only
refer to any object which is a File. -
- But a RestrictedFile is also a File, so f can
also refer to a RestrictedFile object. -
- The type of the reference we use determines the
point of view we will have on the object.
File f new File(story.txt)
File f new RestrictedFile(visa.dat, 12345)
71RestrictedFile point of view
- 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 tree.
RestrictedFile f new RestrictedFile(visa.dat,
12345) f.close() f.lock() f.unlock(12345) Stri
ng s f.toString()
72File point of view
- If we refer to a RestrictedFile object using a
File reference we have the File point of view
which lets us use only methods that are defined
in class File and up the hierarchy tree.
File f new RestrictedFile(visa.dat,
12345) f.close() f.lock() //Cant use this
method f.unlock(12345) //Cant use this
method String s f.toString()
73Object point of view
- If we refer to a RestrictedFile object using an
Object reference we have the Object point of view
which let us see only methods that are defined
in class Object.
Object f new RestrictedFile(visa.dat,
12345) f.close() //Cant use this
method f.lock() //Cant use this
method f.unlock(12345) //Cant use this
method String s f.toString()
74Points of View
RestrictedFile
- toString()
- ...
- isOpen()
- open()
- close()
- lock()
- unlock(key)
- isLocked()
75Compile time-type vs.run-time type
- A variable of a reference type has a declared
type that is known at compile time and never
changes. - File f
- A reference variable may hold values of any
subclass of its declared type - The type of the values held may change during the
running of the algorithm and is not known during
compile time - The run-time type is always some subclass of the
compile-time type.
f new RestrictedFile(visa.dat,12345)
f new File(visa.dat)
76Widening
- 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.dat, 1234)
RestrictedFile referenceRestrictedFile point of
view
File referenceFile point of view
Widening
77Point distanceFrom
/ A point on a grid. / public class Point
/ Computes the distance from
another point _at_param p The given point.
/ public double distanceFrom(Point p)
int dx x-p.x int dy y-p.y
return Math.sqrt(dxdxdydy) //
... more methods
78Pixel
/ Represents a pixel on a graphical area.
/ public class Pixel extends Point // The
color of the pixel private Color color
/ Constructs a new pixel. _at_param
x,y The coordinates of the pixel. _at_param
color The color of the pixel. / public
Pixel(int x, int y, Color color)
super(x,y) this.color color
// ... more methods
79Widening parameters
- 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.
Point p1 Pixel p2 p1 new Point(2, 3) p2
new Pixel(5, 6, Color.red) double d
p1.distanceFrom(p2)
80Compile-time vs. run-time method invocation
- When we invoke a method on an object we always do
it through a reference - The implementation of the method which is most
specific will be chosen. - Java methods are virtual, i.e. the method which
will be invoked is determined by the run-time
type of object and not on the compile-time type
of reference. - The identity of the invoked method is determined
at runtime. - There are languages that use different mechanisms
for method invocation.
81Type of Method is Determined at Runtime
File file if (Math.random() gt 0.5) file
new File(visa.dat) else file new
RestrictedFile(visa.dat, 76543)
file.open()
Will the file be opened if the number randomly
generated is less than 0.5?
82Another ExampleMouse in a Maze
public class Mouse private instance
variables public Point tellLocation( )
public int tellDirection( ) public
Mouse(Maze m) public void makeMove( )
private boolean outside ( ) private
boolean facingWall( ) private void
stepForward( ) private void turnLeft( )
private void turnRight ( )
83Specialization through Inheritance
- So now we want to create two kinds of mice only
makeMove( ) will change - RightMouse will have one strategy (right paw on
wall) - StraightMouse will have another strategy (go
straight, turn right when can't go straight) - No need to duplicate code just make Mouse be a
superclass, and RightMouse and StraightMouse only
need to provide their own makeMove( ) code
84abstract
- We'll let the user specify which kind of mouse he
wants at runtime - The Mouse class will have all the methods and
instance variables, except makeMove( ) - The Mouse class isn't intended to be used
directly we expect it to be subclassed - To enforce this, we explicitly specify in Mouse
that makeMove( ) is supposed to be implemented in
a subclass
85abstract
- public abstract void makeMove( )
- This prototype is included in the Mouse class
- "abstract" tells Java that makeMove( ) is
expected to be defined in a subclass - Any class that includes an abstract method is
itself abstract, and has to be declared abstract
itself - Such an abstract class cannot be instantiated by
a client, you just have to subclass it and define
its abstract methods - So the Mouse class will be abstract
86abstract Class, subclassed
abstract class Mouse
protected boolean _started protected int
_direction etc. public abstract void
makeMove( ) etc. protected boolean facingWall(
) return theMaze.checkWall (_direction,
location)
extends
extends
RightMouse
StraightMouse
public RightMouse() public void makeMove( )
public StraightMouse() public void makeMove(
)
87The new class Mouse
abstract class Mouse public final
int NORTH0, EAST1, SOUTH2,
WEST3 protected Maze _theMaze protected
boolean _started false //true once the maze
is entered protected Point _location //location
of this mouse protected int _direction
//direction mouse is facing public Point
tellLocation( ) return _location public int
tellDirection( ) return _direction
88 public Mouse (Maze m) // Where do I
start? _location m.getStartLocation( ) //
In what direction do I face initially? _directio
n m.getStartDirection( ) _theMaze
m public abstract void makeMove(
) protected boolean outside ( ) // Am I
outside the maze? return _theMaze.outside(_locat
ion)
89 protected boolean facingWall ( ) return
_theMaze.checkWall(_direction, _location) pro
tected void stepForward( ) switch (direction)
case NORTH _location.y-- break case
EAST _location.x break case
SOUTH _location.y break case
WEST _location.x-- break protected
void turnLeft( ) _direction (_direction
3) 4 protected void turnRight( )
_direction (_direction 1) 4
90Definition of class RightMouse
class RightMouse extends Mouse public
RightMouse (Maze aMaze ) super(aMaze)
public void makeMove( ) if (_started)
if ( !outside( ) ) turnRight(
) while ( facingWall( ) ) turnLeft(
) stepForward( ) else
stepForward( ) _started true
91Definition of class StraightMouse
class StraightMouse extends Mouse public
StraightMouse (Maze aMaze ) super(aMaze)
public void makeMove( ) if (_started)
if ( !outside( ) ) if ( facingWall( )
) turnRight( ) makeMove(
) else stepForward( ) else
stepForward( ) _started
true
92Dynamic Generationof the Kind of Mouse
- Now, the main( ) method lets the user dynamically
specify whether the mouse will be a RightMouse
object or a StraightMouse object - The variable referencing the mouse will be of
class "Mouse", but the actual generation of the
object (either type) occurs at runtime
93Runtime Selection
public class MouseMaze public static void main
(String args) Maze theMaze new Maze(
) Mouse speedy selectMouse(theMaze)
private static Mouse selectMouse(Maze theMaze)
SimpleInput sinp new SimpleInput(System.in)
while (true) System.out.print("Choose
RightMouse (0) " "or StraightMouse (1)
") int i sinp.readInt( ) if ( i
0 ) return new RightMouse(theMaze) if ( i
1 ) return new StraightMouse(theMaze)
94Class Inheritance plus Dynamic Method Binding
- speedy is a Mouse, but it might be a RightMouse
or a StraightMouse - When speedy is sent the makeMove( ) message, it
will do whatever is appropriate for the kind of
mouse it is - The combination of Class Inheritance plus Dynamic
Method binding is very powerful, allowing reuse
of code, but flexible response to messages
95Interfaces
- Java has a way of specifying "classes" that
contain nothing but declarations of abstract
methods - These provide no code, just a list of methods
that every subclass has to define - It allows clients to define a method having
formal parameters of the abstract "class", but
whose actual parameters can belong to any class
in its hierarchy
96Interface Declaration
- This is so common that Java provides a special
way of specifying it interface declarations - Interface declarations are like abstract classes,
but are restricted to containing abstract method
declarations and symbolic constant
definitions interface interface_name
definitions of symbolic constants, and
declarations of abstract methods - Like classes, interfaces are placed in separate
files, with the .java extension
97Syntax Differences
- Classes that contain real definitions of these
abstract methods write "implements
interface_name" instead of "extends" - All the methods in the interface are abstract, so
you don't write "abstract" in front of them - All symbolic constants are assumed to be public,
static, and final, so don't write those keywords,
either
98More Importantly!
- A class can implement more than one interface,
while it can only be a subclass of one class
this allows us to use interfaces more flexibly - We might have interfaces I1 and I2, with methods
that class C defines even if C is a subclass of
B, we could still write class C extends
B implements I1, I2
99One Use for Interfaces
- Sometimes interfaces are used to give definitions
of symbolic constants to be used in several
classes public interface Direction int NORTH
0, EAST 1, - Then several other classes implement this
interface public class Maze implements
Direction
100Another use for interfaces
- Define a plotting function that accepts a
function as one of its arguments void plot
(double x0, double x1, double delta, Function
f) // plot f on values x0, x0delta, ,
x1 - We can't pass a function as an argument
- But we can define different objects that respond
to the message "apply( )", and each different
kind of object contains a function
101interface Imposing a Requirement on Classes
interface Function
interface
double apply(double x)
implements
implements
SineFunction
EmpiricalFunction
double apply(double x )
double apply(double x )
102The Role of Interfaces
- Interfaces play a role like the abstract classes
we saw in previous slides - Interfaces are data types in Java, just like
classes are - When a class implements an interface, instances
of the class can be assigned to variables of the
interface type
103What it Looks Like (these are in different files)
void plot (double x0, double x1, double delta,
Function f) // plot f on values x0,
x0delta, , x1 interface
Function double apply(double x)class
SineFunction implements Function double
apply(double x) return Math.sin(x) class
EmpiricalFunction implements Function double
apply(double x)
104Calling them
- Then these are legal calls (assuming appropriate
constructors for SineFunction and
EmpiricalFunction)plot(0.0, 10.0, 0.1, new
SineFunction( ))andplot(0.0, 10.0, 0.1, new
EmpiricalFunction(60, 0.0, 59.0))
105The Point
- The point is, we can use objects of type
SineFunction and of type EmpiricalFunction in the
same context (e.g., as an argument of the plot( )
method) - They'll both implement the interface Function
they both provide a definition of apply( ) - But they may not belong in the same class
hierarchy, logically, and we need not require
that they be in the same hierarchy
106Interfaces can also Inherit
- Interfaces can also be organized conveniently
into inheritance hierarchies interface I extends
J - I actually consists of all the methods and
constants in I itself together with those in J - A class implementing I has to implement all those
methods and constants
107Exception Handling
- Java provides us with a relatively clean way of
catching run-time errors exceptions - An exception is an object
- An exception is a signal that some unusual
situation (like an error) has occurred - When "something goes wrong", an exception object
is generated and passed back in a special way
108Exceptions in Java
- Java actually uses the notion of exception for 3
related (but different) purposes - Errors an internal Java implementation error was
discovered - E.g out of memory
- Runtime exceptions a programming logic error was
discovered - E.g. division by 0
- Checked Exceptions an exceptional case was
discovered - E.g. file not found
109Exceptions in Java
- Errors and Runtime exceptions will usually cause
the program to crash - Checked exceptions should usually be handled by
the programmer
110Occurrence of a runtime exception
public class ExceptionExample public static
void main(String args) int a 2, 4,
6, 8 for(int j 0 j lt a.length j)
System.out.println(aj)
111Program Crash due to a runtime exception
112Runtime exceptions in the Java API
- java.lang.ArithmeticException
- java.lang.NullPointerException
- java.lang.IllegalArgumentException
- java.lang.NegativeArraySizeException
- java.lang.ArrayIndexOutOfBoundsException
- java.lang.ClassCastException
113try, catch, finally
- The try clause establishes a block of code that
might have exceptions or abnormal exits - The try block is followed by zero or more catch
clauses that specify code to handle various types
of exceptions - the finally clause specifies code that will
always be performed, if any part of the try block
is executed (good for cleanup, closing files,
etc.)
114try // Normally this code runs from top of
block to bottom // without problems. But it
sometimes may raise // exceptions or exit the
block via a break, continue, or // return
statementcatch (SomeException e1) // Handle
an exception object e1 of type SomeException //
or of a subclass of that typecatch
(AnotherException e2) // Handle an exception
object e2 of type AnotherException // or of a
subclass of that typefinally // Always
execute this code, after we leave the try
clause, // regardless of whether we leave it,
normally, with an // exception that is caught or
not caught, or because of a // break, continue,
or return statement
115How are throws caught? Recall the runtime stack,
and method calls
void g ( ) System.out.println(A!)
System.out.println(B!)
System.out.println(C!) System.out.println(D
!)
void e ( ) ......obj.f( )...
main (String args) .........obj.e()...
void f ( ) System.out.println(Hi there!)
System.out.println(Nice weather!) ...
obj.g( ) System.out.println(That was
fun!) System.out.println(Time to move
on!)
Method g( )Where we came from f, line 4
top
Method f( )Where we came from e, line 3
Method e( )Where we came from main, line 4
Method main( )
STACK
116throws are handled upthe calling hierarchy
- If an exception object were generated in g( )
(like an array index was out of bound), the
system would first look if it is caught in g( ) - If it's not caught there, the system sees if it
is caught in f( ) then in e( ) finally in main(
) - If not caught at all, the exception object causes
the Java interpreter to print an error message
and a stack trace and exit
void g ( ) System.out.println(A!)
System.out.println(B!)
System.out.println(C!) System.out.println(D
!)
void e ( ) ......obj.f( )...
main (String args) .........obj.e()...
void f ( ) System.out.println(Hi there!)
System.out.println(Nice weather!) ...
obj.g( ) System.out.println(That was
fun!) System.out.println(Time to move
on!)
117Exception Objects
- An exception in Java is an object that is an
instance of some subclass of java.lang.Throwable - Throwable has two standard subclasses,
java.lang.Error and java.lang.Exception. - Exceptions that are subclasses of Error are
generally unrecoverable and need not be caught - Exceptions that are subclasses of Exception
indicate conditions that may be caught and
recovered from
118Exception Objects
- Since exceptions are objects, they can contain
data and define methods - The Throwable object (at the top of the exception
hierarchy) includes a String message to describe
the exception, and this is inherited by all its
descendants the message is extracted via the
method getMessage( ) - A few descendants add their own data (e.g.,
java.io.InterruptedIOException adds the
field public int bytesTransferredto signify
how much of the I/O was complete before the
exception occurred)
119Exception life-cycle
- When a program performs an illegal operation the
following happens - The regular flow of the program stops
- An exception object is created, which
encapsulates the information about the problem
that occurred - The method may try to catch and handle the
exceptional situation - If the method ignores the exception the method
execution ceases. - An exception then appears at the place in which
the method was called - If the exception is not handled anywhere, the
program crashes.
120Declaring Exceptions
- Certain kinds of exceptions need to be declared
in a methods declaration, if they are not
handled inside the methodpublic void open_file(
) throws IOException // Statements that might
generate an // uncaught java.io.IOException - You only need to declare exceptions that are not
subclasses of Error or of RuntimeException these
are just too common to require declaring - An example that does not need to be declared is
ArrayIndexOutOfBoundsException
121Creating our own Exceptions
- We can declare a new exception class, and put it
in the hierarchy of the class Exception - We need two constructors one with no argument,
and one with a single String argument giving a
description of the fault - Let's look at an existing example from the Java
API, to understand how to define our own
122class FileNotFoundException
package java.iopublic class FileNotFoundExceptio
n extends IOException public
FileNotFoundException( ) super( ) public
FileNotFoundException(String s) super(s)
123How would we use it?
package java.iopublic class FileInputStream
extends InputStream public FileInputStream(Str
ing name) throws FileNotFoundException
try fd new FileDescriptor(
) open(name) catch (IOException e)
throw new FileNotFoundException(name)
124OK, so let's create our own
- Declare a new class, GetOuttaHereException, and
have it extend the Exception class - Provide it with two constructors, one that takes
no arguments and one that takes a string argument
(and both call super) - throw new GetOuttaHereException with or without a
string argument
125GetOuttaHereException definition
public class GetOuttaHereException extends
Exception public GetOuttaHereException( )
super( ) public GetOuttaHereException(String
s) super(s)
126Now, use the exception in a method, gateKeeper( )
void gateKeeper (Person candidate) throws
GetOuttaHereException if ( isBum(candidate)
) throw new GetOuttaHereException("You're a
bum!") if ( isBroke(candidate) ) throw new
GetOuttaHereException("You're broke!") if (
doesNotKnowJava(candidate) ) throw new
GetOuttaHereException("You don't know
Java!")
127We will catch the exception in the calling
method, joinClub
void joinClub (Person candidate) try
gateKeeper(candidate) catch
(GetOuttaHereException e) System.out.println("N
o, you can't join the club because "
e.getMessage( )) return
System.out.println("Welcome to the club!")
128Exceptions Hierarchy
- All the classes for indicating run-time errors
are derived from the class java.lang.Throwable. - The object you deliver to the throw statement
must be an instance of class Throwable - The constructor of class Throwable initializes
all the information about the location where the
exception occurred, the state of the run-time
stack etc. In this way this information is set
for every exception object. - The following diagram explains the inheritance
hierarchy for exceptions.
129Throwable class hierarchy
Throwable
Error
Exception
RuntimeException
130Input / Output
- A program often needs to communicate with other
devices. In other words it should receive input
and send output. - There are many types of input sources
- Reading a file from a local disk / diskette
- Receiving a web page from a remote server
- Receiving a communication message through a
network. Receiving a signal from a sensor of a
robot - Scanner, video camera, ...
- Mouse, keyboard, joystick, ...
131Input / Output
- Similarly, there are many types of output
destinations - Writing to a file on a local disk / diskette
- Sending query information to a remote web server
- Sending communication message to a remote host.
Sending a command to a robot controller. - Printing a document to a printer / fax
- Displaying graphics on the screen
- ...
132GUI inputs and outputs
- GUI related inputs and outputs are usually
treated separately. They are given special API - GUI inputs and outputs include receiving mouse,
keyboard and similar events, and displaying
graphics on the screen
133IO API - design goal
- We want to make a distinction between the content
of the data an application receives/sends and the
source/destination of the data - The same kind of data can be stored on different
types of media - Similarly a given media can store different types
of data
134Scenario
- Suppose we have an image processing application.
It can read images, manipulate them and store
them on a permanent storage. - We want our application to be able to read images
from different types of sources - local image files, remote images from the web,
receiving an image from a scanner, ... - We want to be able to output the image to various
types of destinations - save the image to a local file, print the image
on a printer, send the image to a fax recipient,
...
135Scenario
Application
136IO Streams
- We can achieve the separation by designing a
common interface for reading any kind of data,
and common interface for writing any kind of
data. - This interface is implemented by the notion of
input and output streams. - Any input can be represented as a sequence of
bits. For convenience we divide the sequence into
a sequence of bytes. - Similarly any output can be represented as a
growing sequence of bytes.
137IO Streams
12 72 32 17 83
11 7 91 108
Input stream
reading direction
43 55 31 37 34
13 17 1 15
Output stream
writing direction
138Input streams
- An input stream is a sequence of bytes that is
attached to some input source. - You can read data from the stream in a sequential
order. One byte at a time or several bytes at a
time. - Input streams are represented by the abstract
class java.io.InputStream. - Subclasses of InputStream defines input streams
that are related to various data sources - Class InputStream gives a common interface for
receiving data from various types of data sources
139Specific input streams
InputStream
. . .
FileInputStream
PipedInputStream
ByteArrayInputStream
140Class InputStream
- Class java.io.InputStream defines several methods
that support the abstraction of allowing
sequential reading from a stream -
- Reads the next byte from the stream. Return
-1 if the - end of the stream was reached.
-
- Reads up to b.length bytes from the stream
into the array b. Returns the number of bytes
that were read.
public abstract int read() throws IOException
public int read(byte b) throws IOException
141Input streams
-
- Reads up to length bytes from the stream
into the array b from the index offset.
Returns the number of bytes that were read. -
- Closes this input stream and releases any
system resources associated with the stream. - Few additional methods (look up in the API)
public int read(byte b, int offset, int length)
throws IOException
public void close() throws IOException
142Output streams
- An output stream is attached to an output
destination to which you can write data. - You can write data to the stream in a sequential
order. One byte at a time or several bytes at a
time. - Output streams are represented by the abstract
class java.io.OutputStream. - Subclasses of OutputStream defines output streams
that are related to various data destinations - Class OutputStream gives a common interface for
sending data to various types of data destinations
143Specific output streams
OutputStream
. . .
FileOutputStream
PipedOutputStream
ByteArrayOutputStream
144Class OutputStream
- Class java.io.OutputStream defines several
methods that support the abstraction of allowing
sequential writing to a stream - Writes the specified byte (given as an int) to
this output stream. -
- Writes b.length bytes from the specified byte
array to - this output stream.
public abstract void write(int b) throws
IOException
public void write(byte b) throws IOException
145Input streams
- Writes length bytes from the specified byte
array starting at offset off to this output
stream. - Closes this output stream and releases any
system - resources associated with the stream.
- Few additional methods (look up in the API)
public void write(byte b, int offset, int
length) throws IOException
public void close() throws IOException
146Reading/Writing from/to files
- java.io.FileInputStream is a subclass of
InputStream that let you read a file (viewed as a
sequence of bytes) - java.io.FileOutputStream is a subclass of
OutputStream that let you write data to a file
(as a sequence of bytes) - Both classes have constructors that get the path
of the file as a parameter
147Writing to a file
import java.io. class GenerateDiceData
static final int NUMBER_OF_TOSSES 100000
public static void main(String args) try
OutputStream output new
FileOutputStream(dice.dat) for (long
i0 iltNUMBER_OF_TOSSES i) int
randomThrow (int)(Math.random()6)1
output.write(randomThrow)
output.close() catch (IOException ioe)
System.err.println(Couldnt write to
file)
148Reading from a file
import java.io. public class Count6Occurrences
static final int LOOK_FOR 6 public
static void main(String args) long count
0 try InputStream input new
FileInputStream(dice.dat) int result
while ((result input.read()) ! -1)
if (result LOOK_FOR) count
input.close() System.out.println(count
occurrences) catch (IOException ioe)
System.err.println(Couldnt read
from file)
149Downloading a file from the web page
import java.io. import java.net.URL // This
program downloads a file from a given url // and
saves it to the local file // Usage java
Download lturlgt ltfilenamegt public class Download
public static void main(String args)
try download(args0, args1)
catch (ArrayIndexOutOfBoundsException aioobe)
System.err.println(Wrong
usage.) catch (IOException ioe)
System.err.println(Download failed)
150Downloading a file from the web (cont.)
// Downloads a remote file to the local disk.
// source - The url of the remote file //
filename - The name of the target file. private
static void download(String source,
String filename) throws IOException
InputStream input (new URL(source)).openStream()
OutputStream outputnew FileOutputStream(file
name) int b while ((binput.read())!-1
) output.write(b)
output.close()
151Textual vs. binary data
- We often make a distinction between textual data
and other kind of data - We refer to files that stores text as text
files and to other files as binary files.