SlideShare a Scribd company logo
Lecture 3:
More
Constructors,
Scope, Wrappers,
Inheritance, and
Object Oriented
Design.
Java for the Impatient
• Extending classes &
inheriting fields/methods
– Using this and super
– Constructor chaining
– Polymorphism & casting
– Single and multiple
inheritance
– Visibility modifiers
Object Oriented Design
Inheritance
Natural, hierarchical way of organizing things.
Staff Member
Employee Volunteer
Hourly Salaried
Consultant
Think in terms of “is a” relationships:
An Employee is a Staff Member, as
is a Volunteer.
An Hourly worker is a Employee.
A Consultant is a(n) Hourly employee.
(subclass of Hourly)
(subclass of Employee)
(subclass of Staff)
(superclass)
class Animal {
protected String strName = “”;
protected String strNoise = “”;
protected int iNumTimesPerformed = 0;
// constructors, accessors & modifiers go here
public void identifySelf( ) {
System.out.println(“My name is “ + strName);
} // of identifySelf
public void perform ( ) {
doYourThing( );
iNumTimesPerformed++;
} // of perform
public void doYourThing( ) {
; // ‘no-op’ method
} // of doYourThing
} // of Animal
Example
Subclasses
(Dog extends Animal
i.e. “A dog is an animal” or
“All dogs are animals”)
class Dog extends Animal {
public Dog() {
strNoise = “Woof”;
} // of constructor
public void doYourThing ( ) {
identifySelf();
System.out.println(“I am a dog”);
System.out.println(strNoise);
} // of doYourThing
} // of Dog
Recall: The Animal
class had a no-op
method for
doYourThing()
Animal
Dog Cat Human
Subclasses
(Cat extends Animal
i.e. “A cat is an animal” or
“All cats are animals”)
class Cat extends Animal {
public Cat() {
strNoise = “Miaow”;
} // of constructor
public void doYourThing ( ) {
identifySelf();
System.out.println(“I am a cat”);
System.out.println(strNoise);
} // of doYourThing
} // of Cat
Animal
Dog Cat Human
Example (Cont’d)
Dog pickles = new Dog();
pickles.setName(“Pickles”);
pickles.doYourThing();
// output:
// “My name is Pickles”
// “I am a dog”
// “Woof”
Cat abby = new Cat();
abby.setName(“Abby”);
abby.doYourThing();
// output:
// “My name is Abby”
// “I am a cat”
// “Miaow”
Subclasses
(Human extends Animal
i.e. “A human is an animal” or
“All humans are animals”)
class Human extends Animal {
public Human() {
strNoise = “I think therefore I am”;
} // of constructor
public void doYourThing ( ) {
identifySelf();
System.out.println
(“I am a sentient being”);
System.out.println(strNoise);
} // of doYourThing
} // of Human
Animal
Dog Cat Human
Example (Cont’d)
Human descartes = new Human();
descartes.setName(“Rene”);
descartes.doYourThing();
// output:
// “My name is Rene”
// “I am a sentient being”
// “I think therefore I am”
Inheritance and Scope
Variables (e.g. strNoise):
• Java first examines current method, looks for local
variable or parameter;
• Java then examines current class (e.g. Dog);
• Java then examines superclass (e.g. Animal);
• Java continues up the class hierarchy until no more
superclasses to examine.
Methods (e.g. doYourThing() or identifySelf()):
• Java first examines current class;
• Java then examines superclass;
• Java continues up inheritance
hierarchy until no more
superclasses to examine.
Specifying Scope
Java allows you to override the scope rules
by saying which variable/method you’re
referring to:
Keyword super:
keyword for specifying method or variable
from superclass, e.g., super.doYourThing( )
Keyword this:
keyword for specifying method
or variable in current object, e.g.,
this.doYourThing( )
class Dog extends Animal {
public Dog() {
super.strNoise = “Woof”;
} // of constructor
public void doYourThing ( ) {
super.identifySelf();
System.out.println(“I am a dog”);
System.out.println(strNoise);
} // of doYourThing
} // of Dog
Same (in this case) as
strNoise = “Woof”;
and
this.strNoise = “Woof”;
Same (in this case) as
identifySelf();
or
this.identifySelf();
Using super
class Dog extends Animal {
// constructor as before
public void doYourThing() {
identifySelf();
System.out.println(strNoise);
} // of doYourThing
public void identifySelf() {
super.identifySelf();
System.out.println(“I am a dog”);
} // of identifySelf
} // of Dog
Animal
Dog Cat Human
I.e.
this.identifySelf()
(newly defined below)
I.e. the
identifySelf()
(defined in Animal)
class Shape {
public final double PI = 3.14159;
protected String name;
public String getName () {
return (this.name);
} // getName
public int area () {
return (0);
} // area
} // Shape
A geometry example
Shape
Circle
Rectangle
class Rectangle extends Shape {
private int length, width;
Rectangle () {
this(0, 0);
} // constructor
Rectangle (int l, int w) {
this( l, w, “rectangle”);
} // constructor
Rectangle (int l, int w, String n) {
length = l;
width = l;
name = n;
} // constructor
public int area () {
return (length * width);
} // area
public String getName () {
if (length == width)
return ("square");
else
return (super.getName());
} // getName
public String toString () {
String s;
s = new String ("A " +
getName() +
" with length " + length
+ " and width " + width);
return (s);
}
} // toString
} // Rectangle
Java’s rule:
• If first line of constructor is not an explicit call to a
superclass constructor, Java will implicitly put super( ) as
the first line, calling the superclass default constructor.
public Dog() {
strNoise = “Woof”;
} // of constructor
• An exception to this rule: chained constructor call to
this(params)
will defer super( ) call
• To use superclass constructors with
params, call them explicitly,
e.g., super(strName)
Constructors and Inheritance
implied call to Animal() here
Inheritance and Scoping
Examples:
super(xxx) // calls a superclass constructor
super.xxx // accesses superclass’ variable
super.xxx( ) // calls superclass’ method
this(xxx) // calls a current-class constructor
this.xxx // accesses current class’s variable
this.xxx( ) // calls current class’ method
Note: cannot do
super.super<something>
(can achieve this effect via casting,
but rarely should; details later...)
Inheritance and Scoping
class StaffMember {
String strName;
public StaffMember( ) {
System.out.println (“in default StaffMem constr; No Name”);
setName(“No Name”);
} // of constructor
public StaffMember(String strName) {
System.out.println (“in 2nd StaffMem constructior; have a
Name”);
setName(strName);
} // of constructor
public void setName(String strName) {
this.strName = strName;
} // of setName
}// of StaffMember
class Employee1 extends StaffMember {
public Employee1(String strName)
{
setName(strName);
} // of constructor
} // of Employee1
Inheritance and Scoping
Note: Employee has
no local setName()
method
class Employee2 extends StaffMember {
public Employee2(String strName) {
setName(strName);
} // of constructor
public void setName(String strName) {
super.setName(strName);
System.out.println (“Name set”);
}
} // of Employee2
Class Object
• Java provides a base class, Object
• All classes that do not have an extends clause implicitly
inherit
directly fromclass java.lang.Object
Examples:
public boolean equals (Object o)
public boolean String toString ()
• When you create your own toString( ) method
for a class, you are overriding the toString( )
provided by Object.
Object Hierarchy
Animal
Dog Cat Human
Object
Employee
Salaried Hourly
class Object methods:
String toString()
boolean equals(Object obj)
and a few others...
Animal
Dog Cat Human
Object
Employee
Salaried Hourly
Or how about...
Primitive types (e.g., int) are not classes
But sometimes, we may have need to make use of
primitive types in a context that requires that we
manipulate objects, not primitives
e.g. many collection classes are collections of Objects
Java provides a set of wrapper classes (a.k.a. type
wrappers, a.k.a. envelope classes) to support treating
primitives as objects.
It does this by providing a specific class that
corresponds to each primitive data type
They are in java.lang, so the names are
universally available
Wrapper Classes
Wrapper Classes
Class corresponds to Primitive
Boolean boolean
Character char
Byte byte
Short short
Integer int
Long long
Float float
Double double
Each one:
• allows us to manipulate primitives as objects
• contains useful conversion methods.
E.g. Integer contains
static Integer valueOf(String s)
Integer.valueOf(“27”)
is the object corresponding to int 27
• contains useful utility methods (e.g. for hashing)
Using wrappers to bridge between objects and primitives:
// create and initialize an int
int i = 7;
// create an Integer object and convert the int to it
Integer intObject = new Integer( i );
// retrieve the int by unwrapping it from the object
System.out.println( intObject.intValue );
// convert a string into an Integer object
String strS = “27”;
Integer intObject
intObject = new Integer (Integer.valueOf(strS) );
// then to an int
i = intObject.intValue;
Wrapper Classes
A class
method
Instance vs. Class Methods
• Use instance methods whenever each object should have
its own behavior.
e.g.,
pickles vs. descartes vs. abby doYourThing( ).
• Use a class method whenever the class itself should
maintain a single behavior for all instances of the class.
e.g.,
converting from one type to another.
• Class methods cannot be used to access
instance variables
•So you can say
Integer.valueOf(strValue);
but not
intObject.valueOf(strValue);
Polymorphism
• Several subclasses may have different
methods for accomplishing the
same/similar behavior
– You don’t 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 move
• But animals move in diffrerent ways
Polymorphism
class Animal {
public void move ( ) {
System.out.println(“I am an animal and am moving.”);
} // of move
} // of Animal
class Fish extends Animal {
public void move( ) {
System.out.println(“Glug glug gurgle gurgle”);
} // of move
} // of Fish
class Bird extends Animal {
public void move( ) {
System.out.println(“Tweet tweet flap flap”);
} // of move
} // of Bird
Polymorphism (cont’d)
class Dog extends Animal
{
public void move ( )
{
System.out.println(“Sniff sniff woof woof”);
} // of move
public void bark ( )
{
System.out.println(“Arf Arf”);
} // of bark
} // of Dog
class Driver {
public static void main (String[ ] argv) {
Animal[ ] animalArray = new Animal[3];
int iIndex;
animalArray[0] = new Bird( );
animalArray[1] = new Dog( );
animalArray[2] = new Fish( );
for (iIndex=0; iIndex < animalArray.length; iIndex++) {
animalArray[iIndex].move( );
} // of for
} // of main
} // of Driver
Output:
Tweet tweet flap flap
Sniff sniff woof woof
Glug glug gurgle gurgle
Polymorphism
All animals can move,
so any member of the
array can move
Polymorphism
• Polymorphism means “taking many forms” ... an object of a
given class can adapt take the formof any of its subclasses.
• Polymorphism means that the correct move( ) method will
always be called.
• 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: can’t substitute superclass for a
subclass, e.g.,
CANNOT substitute an animal for a bird.
“An animal is a bird?” No.
• A single interface for multiple behaviors:
Only one interface for the method call.
Multiple behaviors based on the subclass.
class Driver2 {
public static void main(String[ ] argv) {
Animal[ ] = animalArray[3];
Dog d;
int iIndex;
animalArray[0] = new Bird( );
animalArray[1] = new Dog( );
animalArray[2] = new Fish( );
for (1=0; 1 < animalArray.length; iIndex++)
if (animalArray[iIndex] instanceof Dog)
{ d = (Dog) animalArray[iIndex];
d.bark( );
} // if
} // main
} // Driver2
Polymorphism
We cast before calling
bark() because only dogs
can bark. So some array
members cannot execute
the method
Casting:
• used here to give an object of a superclass the form of the
appropriate subclass, e.g.,
if (animalArray[iIndex] instanceof Dog)
{
animalArray[iIndex].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 (animalArray[iIndex] instanceof Dog)
{
d = (Dog) animalArray[iIndex]
d.bark( );
}
Polymorphism
Keyword instanceof:
Used to interogate an object to see if it is an instance
of the specified class, e.g.
“Is this particular animal of class Dog?”
Casting … Why?
Question:
If Java can determine that a given Animal is or
is not a Dog (via instanceof), then:
• Why the need to cast it to a Dog object
before Java can recognize that it can bark?
• Why can’t Java do it for us?
Source
code
Compile
Byte
code
JVM
Interpreter
Program
runs
errors errors
Answer:
difference between compile-time and run-
time type checking.
Casting… Why?
Casting (con’td)
Compile-time Errors:
• Those that are
discernable
without the program
executing.
• Question of language
legality:
“Is this a legal
statement?”
e.g.,
iIndex = chVariable;
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.,
animalArray[<badIndex>] = someAnimal
Statement is legal, but particular
index value isn’t.
if (animalArray[iIndex] instanceof Dog) {
animalArray[iIndex].bark;
}
• 1st line is legal.
• 2nd line isn’t (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. We
want most checking at compile-time for
performance and correctness.
Casting… Why?
Casting (Cont’d)
if (animalArray[iIndex] instanceof Dog) {
d = (Dog) animalArray[iIndex];
d.bark( );
}
• 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.
Multiple Inheritance
Some languages allow multiple inheritance:
Animal Pet (two superclasses)
Dog (a subclass of two)
• Multiple inheritance leads to many potentially confusing naming
problems (e.g. Pet.doYourThing() vs. Animal.doYourThing())
•Growing consensus: the benefits of multiple inheritance aren’t
worth the problems.
• Java has single inheritance only.
•Java doesn’t allow multiple inheritance
•Well, there is a restricted kind that avoids
most of the problems. It involves using
interfaces, which we’ll cover later)
Visibility and Access
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 class’s “contract”
Make all fields private
Make all other “private” methods protected
Don’t leave off the modifier unless you know about packages
Can an object use a field or call a method?
Animals (again!)
class Animal {
protected String strName = “”;
protected String strNoise = “”;
// constructors, accessors & modifiers go here
public void identifySelf( ) {
System.out.println(“My name is “ + strName);
} // of identifySelf
public void doYourThing( ) {
; // ‘no-op’ method
} // of doYourThing
} // of Animal
So, any object can ask an
animal to identify itself,
or do its thing.
Exception Handling:
When Bad Things
Happen to Good Code
Error Handling
So far:
• have done very little error handling
• have assumed that things will work as intended
Rules of Thumb:
• programmers must test and debug to find and correct
compile-time errors
• compiler doesn’t solve the problem of run-time errors
(e.g., incorrect values or state)
• programmer must insure that run-time errors
result in “graceful” program behavior
• “graceful” means “the program doesn’t just
produce wrong effects or blow up!
Exceptions--Why?
• In traditional procedural programming languages, there were
various ways of handling run-time errors.
• One way is to return some kind of value indicating whether the
procedure succeeded or not.
For example:
public boolean someMethod( )
{
// if this method suceeded, return true
// otherwise return false
}
Note the blurring of the logical distinction between
procedures and functions… a bad engineering habit!
Exceptions--Traditional Methods
• Traditional means of error handling can quickly become ugly,
complex and unmanageable.
For example:
If we intend to do the sequence of calling three procedures
followed by one or more instructions, e.g.,
someMethod( );
someOtherMethod( );
someThirdMethod( );
/* do some intended actions*/
we can find ourselves with code that looks like . . .
Exceptions--Traditional Methods
if (someMethod( ) == true) {
if (someOtherMethod( ) == true) {
if (someThirdMethod( ) == true) {
// have not encountered errors; do intended actions
}
else {
// handle some error caused by someThirdMethod( )
}
}
else {
// handle some error caused by someOtherMethod( )
}
}
else {
// handle some error caused by someMethod( )
}
Exceptions--Traditional Methods
int iErrorValue = 0;
public void someMethod( ) {
// do someMethod’s stuff here
// if there is an error, then set iErrorValue = 1
}
public void someOtherMethod( ) {
// do someOtherMethod’s stuff here
// if there is an error, then set iErrorValue = 2
}
public void someThirdMethod( ) {
// do someThirdMethod’s stuff here
// if there is an error, then set iErrorValue = 3
}
• Another way error handling is to have the value of a global variable
represent the error.
Exceptions--Global Variables
public void doIt()
{
someMethod();
someOtherMethod();
someLastMethod();
if (iErrorValue == 1)
...
if (iErrorValue == 2)
...
if (iErrorValue == 3)
...
}
But: What if the run-time error
stopped us from continuing?
For example: What if
someMethod( ) failed in such a
way that we cannot go on to
someOtherMethod( )?
To cope, we find ourselves with
code that’s nearly as messy as the
earlier example which featured
multiple nested-ifs:
Exceptions--Global Variables
public void doit( ) {
someMethod( );
if (iErrorValue == 1) {
...
} // if
else {
someOtherMethod( );
if (iErrorValue == 2) {
...
} // if
else {
someThirdMethod( );
if (iErrorValue == 3) {
…
} // if
else {
do intended actions
} // else
} // else
}// else
Exceptions--Global Variables
Note: with this technique
we potentially must wrap
the ENTIRE program
in a series of if/else clauses,
duplicating code in places.
(Do we prefer robustness
or clarity/maintainability?)
• As you can see, it gets convoluted very fast even for such a
simple sequence of steps.
• Historically, the way programmers got around this was simply to
not do any error handling at all!
• Instead, they generally used one of two approaches:
• Upon detecting an error, simply terminate the program, i.e.,
“recognizethe error but don’t handle it, just quit”, or else …
• Don’t even attempt to detect the error; i.e., “let the program
react in anarbitrary and unpredictable manner”(blow up? bad
values? wrong behavior?)
• Both of these violate a basic tenet of structured
programming:
“Allow only a single point of exit from
any procedure or function.”
Exceptions: Traditional Approaches
Both of these traditional approaches boil down to a case of the
programmer simply ignoring the real problem, which is:
When a run-time error occurs in a method,
• how can we stop the method without allowing it to do any
damage?
• how can we take appropriate actions to handle the error without
having the program simply blow up or do something else that’s
bad?
It is not acceptable for programs to fail or to do “bad behavior”!
• Safety critical programs
• Customer satisfaction
We require some mechanism to recover from
unexpected or abnormal run-time situations.
Exceptions: The Real Problem
Exception Handling: the modern programming concept for
dealing with run-time errors
Exception: “a run-time event that may cause a method to fail or to
execute incorrectly”
Purpose of Exception Handling:
“to allow graceful handling of and recovery from run-time
errors”
Common examples in Java:
• NullPointerException
• ArithmeticException
• ArrayIndexOutOfBoundsException
• Java API contains over two dozen exceptions
provided by Java.
Exceptions and Exception Handling
Exception Terminology:
• When an exceptional condition occurs, an exception
is “thrown” (i.e., the exception has been recognized).
• The flow of control is tranferred to the point where the
exception is “caught” (I.e., where the exception-
handling code responds to it).
In the jargon of some other programming languages,
when an exception is recognized, an exception is:
• “raised” (in place of “thrown”), then
• “handled” (in place of “caught”).
Same ideas, different jargon.
Exceptions: Terminology
One is usually
more interested in
the type of the exception
than in manipulating it as an object,
so “e” is just an object often thrown away.
The general structure of Java’s exception handling:
try {
// here goes the code that attempts to perform the
// intended action, but that could throw an exception
...
} // try
catch (ExceptionType1 e) {
// here goes the code to handle exception type 1
...
} // catch Type1
catch (ExceptionType2 e) {
// here goes the code to handle exception type 2
...
} // catch Type2
Exceptions: General Format
int iDivisor;
int iDividend;
float fResult;
try
{
// get input for divisor and dividend
...
fResult = (float) iDividend / iDivisor;
System.out.println(fResult);
}
catch (ArithmeticException e)
{
System.out.println("The divisor was 0");
...
}
Exceptions: Simple Example
An example showing the structure of Java’s exception handling:
See, we don’t
Care about the exception,
Just about its type being arithmetic error.
How Java handles Exceptions:
If an exception is thrown in a method, then you can do one of two
things in response:
1. Catch the exception right then and there, and handle the
exception yourself.
You would do this if you have enough information to know
how to handle the error.
2. Declare in the method header that whoever
called the method has to handle the error.
You would do this if you don't have enough
information to know how to handle the error.
Exceptions: How in Java
Given a full Queue, where a client tries to enqueue an item . . .
• What should you have the Queue do?
• How do you know what it should do?
• Should it print out a message?
• Should it try to increase the Queue’s size?
• Should it not enqueue the item?
• Should it dequeue an item to make room for the new item?
What should you do? To put it simply, you don't know.
Solution:
1. Your design/documentation for enqueue
should state a precondition:
/** PRE/POST: The queue is not full */
2. The code will let the exception propagate.
Exceptions: Example
When an exception is thrown, it must be caught immediately or
declared to be allowed to propagate.
An example of code that will not compile:
class Queue {
...
public boolean isEmpty( ) {
...
} // isEmpty
public void dequeue(Object o) {
if (isEmpty( ) == true)
throw new QueueEmptyException( );
...
} // dequeue
...
} // class Queue
Exceptions: Propagation
Dequeue is not allowed to do this
• Results in an error saying that dequeue must catch or declare
QueueEmptyException.
• To resolve this, modify dequeue so that the exception is
declared to be thrown:
public void dequeue(Object o) throws QueueEmptyException {
if (isEmpty( ) == true)
throw new QueueEmptyException( );
...
}
• The method header above declares that this
method can throw a
QueueEmptyException
and that the method calling dequeue( ) must plan
on catching the QueueEmptyException.
Exceptions: Propagation
Suppose you want to use this Queue class to simulate
a line of Customers, and you do:
class Customer {
...
} // Customer
class Cashier {
Queue customerQueue = new Queue( );
...
public void getNextCustomer( ) {
Customer cust;
...
cust = (Customer) customerQueue.dequeue( );
...
} // getNextCustomer
...
} // Cashier
Exceptions: Example
This will result in a compile-time error because method
getNextCustomer must:
• catch exception QueueEmptyException, or
• declare that QueueEmptyException propagates upwards
Thus, we can repair getNextCustomer in one of two ways:
• Option 1: have it catch exception QueueEmptyException
• Option 2: have it declare that this method allows
QueueEmptyException to propagate
Exceptions: Example (cont’d)
public void getNextCustomer( )
{
Customer cust;
try {
...
cust = (Customer) customerQueue.dequeue( );
...
} // try
catch (QueueEmptyException e) {
// handle the QueueEmptyException here
...
} // catch
} // getNextCustomer
An Exception: Catching It
Option 1
public void getNextCustomer( ) throws QueueEmptyException
{
Customer cust;
...
cust = (Customer) customerQueue.dequeue( );
...
} // getNextCustomer
This option dictates that whoever calls method
getNextCustomer( )
has the responsibility of handling the exception.
An Exception:
Declaring that it will propagate
Option 2
public class Test {
public static void A( ) {
int array[ ] = new int[5];
try {
System.out.println( "In A's try." );
array[ 5 ] = 1;
} // try
catch( ArrayIndexOutOfBoundsException error ) {
System.out.println( "In A's catch." );
} // catch
} // A()
public static void main( String argv[ ] ) {
try {
A( );
} // try
catch( Exception e ) {
System.out.println( "In main's catch." );
} // catch
System.out.println( "After try in main." );
} // class Test
Exceptions: Another Example
Output:
In A's try.
In A's catch.
After try in main.
What happens here?
• To recognize the exceptional state, use standard if-else logic.
• To respond to them, you can create your own Exceptions.
Exceptions are objects
So you really define your own classes of exception
• All Exceptions you create are extensions of java.lang.Exception
For example:
class QueueEmptyException extends Exception
{
public QueueEmptyException( ) { }
public QueueEmptyException(String strMessage)
{
super(strMessage);
}
}
Exceptions: Creating Your Own
• You can take advantage of inheritance when dealing with
exceptions.
• Suppose we had an inheritance hierarchy of exceptions like this:
• You can have more than one catch block for a try block.
• A catch block will only catch that exception
or a subclass of that exception.
Exception
IOException QueueFullException
EOFException
FileNotFoundException
Inheritance and Exceptions
try {
...
} // try
catch (QueueFullException e) {
...
} // catch QueueFull Exception
catch (FileNotFoundException e) {
...
} // catch FileNotFound Exception
catch (IOException e) {
...
} // catch IO Exception
Inheritance and Exceptions
This sequence of catches works:
Exception
IOException QueueFullException
EOFException
FileNotFoundException
try {
...
} // try
catch (IOException e) {
...
} // catch IOException
catch (FileNotFoundException e) {
...
// this code can never be reached because
// FileNotFound is subclass of IOException
} // catch FileNotFound Exception
This sequence of catches doesn’t work:
Inheritance and Exceptions
Exception
IOException QueueFullException
EOFException
FileNotFoundException
Something you can do with exceptions:
try {
...
} // try
catch (QueueFullException e) {
...
} // catch QueueFullException
catch (IOException e) {
...
} // catch IOException
catch (Exception e) {
...
// this will catch any other kind of exception
// since all exceptions extend Exception
} // catch base Exception
Inheritance and Exceptions
“catch-all” handler
• In Java, there are actually two types of Exceptions:
• those subclassed from Exception
• those subclassed from RuntimeException
A technoid annoyance: Both kinds deal with run-time errors
• Those subclassed from RuntimeException do not have to be
explicitly caught or declared in the method header.
• This is good. It prevents code from being cluttered with
exception handling:
// possible ArrayIndexOutOfBounds
customerArray[10] = new Customer( );
// possible ArithmeticException
x = y / z;
• These may still be caught and/or propagated
upwards like normal exceptions.
Exception & RuntimeException
• There is a problem with the internal state of the
program
• A contract is violated
• A security risk arises (SecurityException)
• There is an error with an object or the data it
manipulates.
• Coping with bad parameters
• Dealing with Truly Exceptional conditions
(memory, stack).
Exceptions: When to Use
When to use exceptions: Internal State
For example:
public int getAge(int iSocialSecurityNumber)
throws RecordKeepingException
{
int index = getHashKey(iSocialSecurityNumber);
int iAge = myArray[index].getAge(iSocialSecurityNumber);
/* Similar to util.ASSERT( ) statement. */
if (iAge <= 0)
throw new RecordKeepingException
(“Exception: Age for “ + iSocialSecurityNumber +
“ not in range: “ + iAge);
else
return iAge;
}
public TreeNode getNodeRecursively
(int index, TreeNode currentNode)
throws MissingNodeException {
if (currentNode == null) {
throw new MissingNodeException
(“Exception: No node with ” + index + “ found”);
} // if
else if (currentNode.getNumber() == index) {
return currentNode;
} // else
else if (currentNode.getNumber() > index) {
return getNodeRecursively (index,
currentNode.getLeftChild());
} // if
else {
return getNodeRecursively (index,
currentNode.getRightChild());
} // else
}// getNodeRecursively
When to Use Exceptions: Contract Violated
public void initializeTreeNode(int iNumberNodes) {
if (myTree == null) {
if (DEBUG)
System.out.println (“Null tree found!”);
throw new NullPointerException (“Null tree found”);
/* NOTE: Runtime exception;
no need to declare propagation */
}
else {
for (int i=0; i < iNumberNodes; i++) { {
TreeNode newNode = new TreeNode( i );
tree.insertNode(newNode);
}
}
} // initializeTreeNode
When to Use Exceptions: Error with objects
public Integer convertNumber (String strToConvert) {
for (int i =0; I < strToConvert.length(); i++) {
char chTemp = strToConvert.charAt(i);
if (!Character.isDigit(chTemp)) {
if (DEBUG) System.out.println
(“Bad input String: “ + strToConvert);
throw new NumberFormatException(“Exception: “ +
strToConvert + “ is not numeric”);
}
}
} // convertNumber
When to Use Exceptions: Bad Parameters
public class Chat {
public static void doStuff() {
Listener.count(”Yes it is ");
try {
Chit.doStuff();
} //try
catch (StackOverflowError e){
System.exit(0);
} // catch
}
} // Chat
When to Use Exceptions:
Truly Exceptional Circumstances
public class Chit {
public static void doStuff() {
Listener.count(”No it isn’t ");
try {
Chat.doStuff();
} // try
catch (StackOverflowError e) {
System.exit(0);
} // catch
}
} // Chit
public class Listener {
static int iCount;
public static void count(String strSpeaker){
iCount++;
System.out.println (strSpeaker + " is number " + iCount);
}
} // Listener
When to Use Exceptions:
Truly Exceptional Circumstances
public TreeNode getNode(int index)
{
TreeNode tempNode;
try {
tempNode =
myTree.getNodeRecursively(new TreeNode(index));
} // try
catch(StackOverflowError e) {
System.exit(1);
} // catch
return tempNode;
} // getNode Or less obviously
• Print an error message
• Log the exception
• Retry the method
(maybe with default parameters)
• Restore the system to some previously
known "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.
When Catching Exceptions you can . . .
OOA/OOD/OOP
“Who”/what knows
enough to handle
the exception?
local?
high-level?
Exception Defined:
Object that defines an unusual or erroneous situation
What to do?
Not handle the exception (program halts. Ugh!)
Handle the exception where it occurs (try...catch...)
Handle the exception at another point in the program
(exception propagation)
Throwing an exception:
Part of the contract of a method (throws)
Responsibility of the client to handle (try…catch…)
Exceptions: Review
A Few Words
on Vectors
Vectors
• An array (list) that dynamically resizes
itself to whatever size is needed.
• A partial API for Vector:
class Vector {
public void addElement( Object obj )
public boolean contains(Object elem)
public Object elementAt(int index)
public Object firstElement()
public int indexOf(Object elem)
public void insertElementAt(Object obj, int index)
public boolean isEmpty()
public Object lastElement()
public int lastIndexOf(Object elem)
public void removeAllElements()
public boolean removeElement(Object obj)
public void removeElementAt(int index)
public void setElementAt(Object obj, int index)
public int size()
} // of Vector
Vectors
• Vector is a class.
• Must have an object of type Vector instantiated via new( )
to get an instance of Vector.
• All rules of good OO programming apply.
• Thus, access by requesting services via methods, not via
direct access (such an array).
size( ) returns current number of elements.
elementAt(int index) returns reference to
element at specified index.
insertElementAt( Object obj, int index )
insertion into linked list (but slower);
addElement (Object obj) adds to end.
Common
Examples
Vectors
Vectors:
• Can be populated only with objects;
• Cannot be populated with primitives;
• Can be populated with objects that contain primitives;
• If you need to populate them with primitives, use type
wrapper
classes e.g., Integer for int, etc.
• Will allow you to populate them with any type of object . .
.
• Thus, good programming requires that the programmer
enforce
typing within a Vector, because Java doesn’t.
Vectors
Vectors and casting:
• Vectors are a subclass of class Object.
• Thus, vectors can handle any class of object (i.e., no
type
checking)
• Thus, must cast any object obtained from a Vector
before invoking any methods not defined in class Object.
Vector v = new Vector ( );
Student s = new Student( “Joe” );
Student otherStudent;
v.addElement( s );
otherStudent = (Student) v.elementAt(0);
// Assume we have vector v and int k.
// Assume int k is an index within the
// range [0..(v.size( ) - 1)].
Object o;
o = v.elementAt(k); // no cast needed, already Object
if (o instanceof Student)
{
// do stuff for Student
}
if (o instanceof Cafeteria)
{
// do stuff for Cafeteria
}
Vectors
Vectors and instanceof:
Design issue:
This example is legal Java, but
is it good programming?
Vectors and Arrays
Arrays: statically sized
Vectors: dynamically sized
Arrays: can directly access, e.g.,
myArray[6]
but shouldn’t
(except maybe within the class in
which they’re declared IF
efficiency concerns;
or for testing purposes.)
Vectors: must use methods to access.
Vector services provide a good model for
the Array services you should implement.
Vectors versus Linked Lists
Can use Vectors to simulate a Linked List:
• Don’t want direct access to data, so . . .
• Provide methods for getPrevious( ), getNext( ), etc. that
do the
std. Linked List things.
• While the list is implemented as a Vector, the client uses it
as if
it’s a Linked List.
BUT . . .
There are performance implications (that may or may not
matter for a given instance).
What is the cost of:
• insertion?
• deletion?
Vectors versus Linked Lists
For ordered Linked Lists:
• cost of traversal to locate target: O(N)
• cost of insert/delete: O(1)
• total cost: O(N)
For ordered Vector:
• cost of traversal to locate target: O(N)
(if accessible via direct access, then O(1) )
• insertion or deletion of element implies (average case),
moving
O(N) elements
• total cost: O(N)
Thus, at first glance, equivalent…
But what does Big Oh hide here?
• Linked Lists: search thru N/2, plus insert/delete
• Vectors: search thru N/2, plus moving N/2
Thus, Vectors
imply twice
the work
Vector Capacity
• Capacity is dynamic
• Capacity can grow and shrink to fit needs
• Capacity grows upon demand
• Capactiy shrinks when you tell it to do so via method
trimToSize( )
• Using trimToSize( ) implies performance costs upon
subsequent
insertion.
• When extra capacity is needed, then it
grows by how much?
• Depends on which of three constructors is used . . .
Vector Capacity
Three Vector constructors:
• public Vector (int initialCapacity, int capacityIncrements);
• public Vector (int initialCapacity);
• public Vector( );
First constructor (2 parameters):
• begins with initialCapacity
• if/when it needs to grow, it grows by size
capacityIncrements.
Second constructor( 1 parameter):
• begins with initialCapacity
• if/when needs to grow, it grows by doubling
current size.
Third construtor (no parameters):
• begins with capacity of 10
• if/when needs to grow, it grows by doubling
current size.

More Related Content

PPTX
Pi j3.1 inheritance
mcollison
 
PPT
InheritanceAndPolymorphismprein Java.ppt
gayatridwahane
 
PPT
06 InheritanceAndPolymorphism.ppt
ParikhitGhosh1
 
PPTX
encapsulation, inheritance, overriding, overloading
Shivam Singhal
 
PPTX
Java chapter 5
Abdii Rashid
 
PDF
Java programming -Object-Oriented Thinking- Inheritance
Jyothishmathi Institute of Technology and Science Karimnagar
 
PPTX
Oop inheritance chapter 3
Narayana Swamy
 
PPTX
Java Inheritance - sub class constructors - Method overriding
NithyaN19
 
Pi j3.1 inheritance
mcollison
 
InheritanceAndPolymorphismprein Java.ppt
gayatridwahane
 
06 InheritanceAndPolymorphism.ppt
ParikhitGhosh1
 
encapsulation, inheritance, overriding, overloading
Shivam Singhal
 
Java chapter 5
Abdii Rashid
 
Java programming -Object-Oriented Thinking- Inheritance
Jyothishmathi Institute of Technology and Science Karimnagar
 
Oop inheritance chapter 3
Narayana Swamy
 
Java Inheritance - sub class constructors - Method overriding
NithyaN19
 

Similar to Java for the Impatient, Java Constructors, Scope, Wrappers, Inheritance, and Object Oriented Design lecture .PPT (20)

PPT
RajLec10.ppt
Rassjb
 
PPSX
Java.lang.object
Soham Sengupta
 
PPTX
METHOD OVERLOADING AND INHERITANCE INTERFACE
mohanrajm63
 
PPTX
OBJECT ORIENTED PROGRAMMING STRUCU2.pptx
JeevaR43
 
PPT
Object concepts
Aashima Wadhwa
 
PPT
chap11.ppt
MonishaAb1
 
PPT
Java tutorial for Beginners and Entry Level
Ramrao Desai
 
PPT
Chapter 8 Inheritance
OUM SAOKOSAL
 
PDF
Inheritance
Sardar Alam
 
PPT
Object concepts
Venkatesh Boyina
 
PPTX
Ch5 inheritance
HarshithaAllu
 
PPTX
Core java oop
Parth Shah
 
PPT
Introductory Example: A Trip to the Aviary.ppt
saikatmondal9955
 
PPT
Lecture d-inheritance
Tej Kiran
 
PDF
Java Inheritance
Rosie Jane Enomar
 
PPT
Chapter 5 (OOP Principles).ppt
henokmetaferia1
 
PPTX
Chapter 8.2
sotlsoc
 
PPTX
UNIT 5.pptx
CurativeServiceDivis
 
PPTX
Java presentation
Akteruzzaman .
 
RajLec10.ppt
Rassjb
 
Java.lang.object
Soham Sengupta
 
METHOD OVERLOADING AND INHERITANCE INTERFACE
mohanrajm63
 
OBJECT ORIENTED PROGRAMMING STRUCU2.pptx
JeevaR43
 
Object concepts
Aashima Wadhwa
 
chap11.ppt
MonishaAb1
 
Java tutorial for Beginners and Entry Level
Ramrao Desai
 
Chapter 8 Inheritance
OUM SAOKOSAL
 
Inheritance
Sardar Alam
 
Object concepts
Venkatesh Boyina
 
Ch5 inheritance
HarshithaAllu
 
Core java oop
Parth Shah
 
Introductory Example: A Trip to the Aviary.ppt
saikatmondal9955
 
Lecture d-inheritance
Tej Kiran
 
Java Inheritance
Rosie Jane Enomar
 
Chapter 5 (OOP Principles).ppt
henokmetaferia1
 
Chapter 8.2
sotlsoc
 
Java presentation
Akteruzzaman .
 
Ad

Recently uploaded (20)

PDF
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
PDF
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
PDF
Exploring AI Agents in Process Industries
amoreira6
 
PDF
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PDF
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pdf
Certivo Inc
 
PPTX
EU POPs Limits & Digital Product Passports Compliance Strategy 2025.pptx
Certivo Inc
 
PDF
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
PPTX
AZ900_SLA_Pricing_2025_LondonIT (1).pptx
chumairabdullahph
 
PPTX
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
PPTX
Role Of Python In Programing Language.pptx
jaykoshti048
 
PPTX
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
PPTX
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
PDF
Community & News Update Q2 Meet Up 2025
VictoriaMetrics
 
DOCX
The Future of Smart Factories Why Embedded Analytics Leads the Way
Varsha Nayak
 
PPTX
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
PPTX
AIRLINE PRICE API | FLIGHT API COST |
philipnathen82
 
PPTX
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
PDF
Multi-factor Authentication (MFA) requirement for Microsoft 365 Admin Center_...
Q-Advise
 
PDF
Become an Agentblazer Champion Challenge
Dele Amefo
 
PDF
A REACT POMODORO TIMER WEB APPLICATION.pdf
Michael624841
 
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
Build Multi-agent using Agent Development Kit
FadyIbrahim23
 
Exploring AI Agents in Process Industries
amoreira6
 
Teaching Reproducibility and Embracing Variability: From Floating-Point Exper...
University of Rennes, INSA Rennes, Inria/IRISA, CNRS
 
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pdf
Certivo Inc
 
EU POPs Limits & Digital Product Passports Compliance Strategy 2025.pptx
Certivo Inc
 
ShowUs: Pharo Stream Deck (ESUG 2025, Gdansk)
ESUG
 
AZ900_SLA_Pricing_2025_LondonIT (1).pptx
chumairabdullahph
 
AI-Ready Handoff: Auto-Summaries & Draft Emails from MQL to Slack in One Flow
bbedford2
 
Role Of Python In Programing Language.pptx
jaykoshti048
 
The-Dawn-of-AI-Reshaping-Our-World.pptxx
parthbhanushali307
 
Odoo Integration Services by Candidroot Solutions
CandidRoot Solutions Private Limited
 
Community & News Update Q2 Meet Up 2025
VictoriaMetrics
 
The Future of Smart Factories Why Embedded Analytics Leads the Way
Varsha Nayak
 
PFAS Reporting Requirements 2026 Are You Submission Ready Certivo.pptx
Certivo Inc
 
AIRLINE PRICE API | FLIGHT API COST |
philipnathen82
 
Maximizing Revenue with Marketo Measure: A Deep Dive into Multi-Touch Attribu...
bbedford2
 
Multi-factor Authentication (MFA) requirement for Microsoft 365 Admin Center_...
Q-Advise
 
Become an Agentblazer Champion Challenge
Dele Amefo
 
A REACT POMODORO TIMER WEB APPLICATION.pdf
Michael624841
 
Ad

Java for the Impatient, Java Constructors, Scope, Wrappers, Inheritance, and Object Oriented Design lecture .PPT

  • 1. Lecture 3: More Constructors, Scope, Wrappers, Inheritance, and Object Oriented Design. Java for the Impatient
  • 2. • Extending classes & inheriting fields/methods – Using this and super – Constructor chaining – Polymorphism & casting – Single and multiple inheritance – Visibility modifiers Object Oriented Design
  • 3. Inheritance Natural, hierarchical way of organizing things. Staff Member Employee Volunteer Hourly Salaried Consultant Think in terms of “is a” relationships: An Employee is a Staff Member, as is a Volunteer. An Hourly worker is a Employee. A Consultant is a(n) Hourly employee. (subclass of Hourly) (subclass of Employee) (subclass of Staff) (superclass)
  • 4. class Animal { protected String strName = “”; protected String strNoise = “”; protected int iNumTimesPerformed = 0; // constructors, accessors & modifiers go here public void identifySelf( ) { System.out.println(“My name is “ + strName); } // of identifySelf public void perform ( ) { doYourThing( ); iNumTimesPerformed++; } // of perform public void doYourThing( ) { ; // ‘no-op’ method } // of doYourThing } // of Animal Example
  • 5. Subclasses (Dog extends Animal i.e. “A dog is an animal” or “All dogs are animals”) class Dog extends Animal { public Dog() { strNoise = “Woof”; } // of constructor public void doYourThing ( ) { identifySelf(); System.out.println(“I am a dog”); System.out.println(strNoise); } // of doYourThing } // of Dog Recall: The Animal class had a no-op method for doYourThing() Animal Dog Cat Human
  • 6. Subclasses (Cat extends Animal i.e. “A cat is an animal” or “All cats are animals”) class Cat extends Animal { public Cat() { strNoise = “Miaow”; } // of constructor public void doYourThing ( ) { identifySelf(); System.out.println(“I am a cat”); System.out.println(strNoise); } // of doYourThing } // of Cat Animal Dog Cat Human
  • 7. Example (Cont’d) Dog pickles = new Dog(); pickles.setName(“Pickles”); pickles.doYourThing(); // output: // “My name is Pickles” // “I am a dog” // “Woof” Cat abby = new Cat(); abby.setName(“Abby”); abby.doYourThing(); // output: // “My name is Abby” // “I am a cat” // “Miaow”
  • 8. Subclasses (Human extends Animal i.e. “A human is an animal” or “All humans are animals”) class Human extends Animal { public Human() { strNoise = “I think therefore I am”; } // of constructor public void doYourThing ( ) { identifySelf(); System.out.println (“I am a sentient being”); System.out.println(strNoise); } // of doYourThing } // of Human Animal Dog Cat Human
  • 9. Example (Cont’d) Human descartes = new Human(); descartes.setName(“Rene”); descartes.doYourThing(); // output: // “My name is Rene” // “I am a sentient being” // “I think therefore I am”
  • 10. Inheritance and Scope Variables (e.g. strNoise): • Java first examines current method, looks for local variable or parameter; • Java then examines current class (e.g. Dog); • Java then examines superclass (e.g. Animal); • Java continues up the class hierarchy until no more superclasses to examine. Methods (e.g. doYourThing() or identifySelf()): • Java first examines current class; • Java then examines superclass; • Java continues up inheritance hierarchy until no more superclasses to examine.
  • 11. Specifying Scope Java allows you to override the scope rules by saying which variable/method you’re referring to: Keyword super: keyword for specifying method or variable from superclass, e.g., super.doYourThing( ) Keyword this: keyword for specifying method or variable in current object, e.g., this.doYourThing( )
  • 12. class Dog extends Animal { public Dog() { super.strNoise = “Woof”; } // of constructor public void doYourThing ( ) { super.identifySelf(); System.out.println(“I am a dog”); System.out.println(strNoise); } // of doYourThing } // of Dog Same (in this case) as strNoise = “Woof”; and this.strNoise = “Woof”; Same (in this case) as identifySelf(); or this.identifySelf();
  • 13. Using super class Dog extends Animal { // constructor as before public void doYourThing() { identifySelf(); System.out.println(strNoise); } // of doYourThing public void identifySelf() { super.identifySelf(); System.out.println(“I am a dog”); } // of identifySelf } // of Dog Animal Dog Cat Human I.e. this.identifySelf() (newly defined below) I.e. the identifySelf() (defined in Animal)
  • 14. class Shape { public final double PI = 3.14159; protected String name; public String getName () { return (this.name); } // getName public int area () { return (0); } // area } // Shape A geometry example Shape Circle Rectangle
  • 15. class Rectangle extends Shape { private int length, width; Rectangle () { this(0, 0); } // constructor Rectangle (int l, int w) { this( l, w, “rectangle”); } // constructor Rectangle (int l, int w, String n) { length = l; width = l; name = n; } // constructor public int area () { return (length * width); } // area public String getName () { if (length == width) return ("square"); else return (super.getName()); } // getName public String toString () { String s; s = new String ("A " + getName() + " with length " + length + " and width " + width); return (s); } } // toString } // Rectangle
  • 16. Java’s rule: • If first line of constructor is not an explicit call to a superclass constructor, Java will implicitly put super( ) as the first line, calling the superclass default constructor. public Dog() { strNoise = “Woof”; } // of constructor • An exception to this rule: chained constructor call to this(params) will defer super( ) call • To use superclass constructors with params, call them explicitly, e.g., super(strName) Constructors and Inheritance implied call to Animal() here
  • 17. Inheritance and Scoping Examples: super(xxx) // calls a superclass constructor super.xxx // accesses superclass’ variable super.xxx( ) // calls superclass’ method this(xxx) // calls a current-class constructor this.xxx // accesses current class’s variable this.xxx( ) // calls current class’ method Note: cannot do super.super<something> (can achieve this effect via casting, but rarely should; details later...)
  • 18. Inheritance and Scoping class StaffMember { String strName; public StaffMember( ) { System.out.println (“in default StaffMem constr; No Name”); setName(“No Name”); } // of constructor public StaffMember(String strName) { System.out.println (“in 2nd StaffMem constructior; have a Name”); setName(strName); } // of constructor public void setName(String strName) { this.strName = strName; } // of setName }// of StaffMember
  • 19. class Employee1 extends StaffMember { public Employee1(String strName) { setName(strName); } // of constructor } // of Employee1 Inheritance and Scoping Note: Employee has no local setName() method class Employee2 extends StaffMember { public Employee2(String strName) { setName(strName); } // of constructor public void setName(String strName) { super.setName(strName); System.out.println (“Name set”); } } // of Employee2
  • 20. Class Object • Java provides a base class, Object • All classes that do not have an extends clause implicitly inherit directly fromclass java.lang.Object Examples: public boolean equals (Object o) public boolean String toString () • When you create your own toString( ) method for a class, you are overriding the toString( ) provided by Object.
  • 21. Object Hierarchy Animal Dog Cat Human Object Employee Salaried Hourly class Object methods: String toString() boolean equals(Object obj) and a few others... Animal Dog Cat Human Object Employee Salaried Hourly Or how about...
  • 22. Primitive types (e.g., int) are not classes But sometimes, we may have need to make use of primitive types in a context that requires that we manipulate objects, not primitives e.g. many collection classes are collections of Objects Java provides a set of wrapper classes (a.k.a. type wrappers, a.k.a. envelope classes) to support treating primitives as objects. It does this by providing a specific class that corresponds to each primitive data type They are in java.lang, so the names are universally available Wrapper Classes
  • 23. Wrapper Classes Class corresponds to Primitive Boolean boolean Character char Byte byte Short short Integer int Long long Float float Double double Each one: • allows us to manipulate primitives as objects • contains useful conversion methods. E.g. Integer contains static Integer valueOf(String s) Integer.valueOf(“27”) is the object corresponding to int 27 • contains useful utility methods (e.g. for hashing)
  • 24. Using wrappers to bridge between objects and primitives: // create and initialize an int int i = 7; // create an Integer object and convert the int to it Integer intObject = new Integer( i ); // retrieve the int by unwrapping it from the object System.out.println( intObject.intValue ); // convert a string into an Integer object String strS = “27”; Integer intObject intObject = new Integer (Integer.valueOf(strS) ); // then to an int i = intObject.intValue; Wrapper Classes A class method
  • 25. Instance vs. Class Methods • Use instance methods whenever each object should have its own behavior. e.g., pickles vs. descartes vs. abby doYourThing( ). • Use a class method whenever the class itself should maintain a single behavior for all instances of the class. e.g., converting from one type to another. • Class methods cannot be used to access instance variables •So you can say Integer.valueOf(strValue); but not intObject.valueOf(strValue);
  • 26. Polymorphism • Several subclasses may have different methods for accomplishing the same/similar behavior – You don’t 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 move • But animals move in diffrerent ways
  • 27. Polymorphism class Animal { public void move ( ) { System.out.println(“I am an animal and am moving.”); } // of move } // of Animal class Fish extends Animal { public void move( ) { System.out.println(“Glug glug gurgle gurgle”); } // of move } // of Fish class Bird extends Animal { public void move( ) { System.out.println(“Tweet tweet flap flap”); } // of move } // of Bird
  • 28. Polymorphism (cont’d) class Dog extends Animal { public void move ( ) { System.out.println(“Sniff sniff woof woof”); } // of move public void bark ( ) { System.out.println(“Arf Arf”); } // of bark } // of Dog
  • 29. class Driver { public static void main (String[ ] argv) { Animal[ ] animalArray = new Animal[3]; int iIndex; animalArray[0] = new Bird( ); animalArray[1] = new Dog( ); animalArray[2] = new Fish( ); for (iIndex=0; iIndex < animalArray.length; iIndex++) { animalArray[iIndex].move( ); } // of for } // of main } // of Driver Output: Tweet tweet flap flap Sniff sniff woof woof Glug glug gurgle gurgle Polymorphism All animals can move, so any member of the array can move
  • 30. Polymorphism • Polymorphism means “taking many forms” ... an object of a given class can adapt take the formof any of its subclasses. • Polymorphism means that the correct move( ) method will always be called. • 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: can’t substitute superclass for a subclass, e.g., CANNOT substitute an animal for a bird. “An animal is a bird?” No. • A single interface for multiple behaviors: Only one interface for the method call. Multiple behaviors based on the subclass.
  • 31. class Driver2 { public static void main(String[ ] argv) { Animal[ ] = animalArray[3]; Dog d; int iIndex; animalArray[0] = new Bird( ); animalArray[1] = new Dog( ); animalArray[2] = new Fish( ); for (1=0; 1 < animalArray.length; iIndex++) if (animalArray[iIndex] instanceof Dog) { d = (Dog) animalArray[iIndex]; d.bark( ); } // if } // main } // Driver2 Polymorphism We cast before calling bark() because only dogs can bark. So some array members cannot execute the method
  • 32. Casting: • used here to give an object of a superclass the form of the appropriate subclass, e.g., if (animalArray[iIndex] instanceof Dog) { animalArray[iIndex].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 (animalArray[iIndex] instanceof Dog) { d = (Dog) animalArray[iIndex] d.bark( ); } Polymorphism
  • 33. Keyword instanceof: Used to interogate an object to see if it is an instance of the specified class, e.g. “Is this particular animal of class Dog?” Casting … Why? Question: If Java can determine that a given Animal is or is not a Dog (via instanceof), then: • Why the need to cast it to a Dog object before Java can recognize that it can bark? • Why can’t Java do it for us?
  • 35. Casting (con’td) Compile-time Errors: • Those that are discernable without the program executing. • Question of language legality: “Is this a legal statement?” e.g., iIndex = chVariable; 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., animalArray[<badIndex>] = someAnimal Statement is legal, but particular index value isn’t.
  • 36. if (animalArray[iIndex] instanceof Dog) { animalArray[iIndex].bark; } • 1st line is legal. • 2nd line isn’t (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. We want most checking at compile-time for performance and correctness. Casting… Why?
  • 37. Casting (Cont’d) if (animalArray[iIndex] instanceof Dog) { d = (Dog) animalArray[iIndex]; d.bark( ); } • 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.
  • 38. Multiple Inheritance Some languages allow multiple inheritance: Animal Pet (two superclasses) Dog (a subclass of two) • Multiple inheritance leads to many potentially confusing naming problems (e.g. Pet.doYourThing() vs. Animal.doYourThing()) •Growing consensus: the benefits of multiple inheritance aren’t worth the problems. • Java has single inheritance only. •Java doesn’t allow multiple inheritance •Well, there is a restricted kind that avoids most of the problems. It involves using interfaces, which we’ll cover later)
  • 39. Visibility and Access 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 class’s “contract” Make all fields private Make all other “private” methods protected Don’t leave off the modifier unless you know about packages Can an object use a field or call a method?
  • 40. Animals (again!) class Animal { protected String strName = “”; protected String strNoise = “”; // constructors, accessors & modifiers go here public void identifySelf( ) { System.out.println(“My name is “ + strName); } // of identifySelf public void doYourThing( ) { ; // ‘no-op’ method } // of doYourThing } // of Animal So, any object can ask an animal to identify itself, or do its thing.
  • 41. Exception Handling: When Bad Things Happen to Good Code
  • 42. Error Handling So far: • have done very little error handling • have assumed that things will work as intended Rules of Thumb: • programmers must test and debug to find and correct compile-time errors • compiler doesn’t solve the problem of run-time errors (e.g., incorrect values or state) • programmer must insure that run-time errors result in “graceful” program behavior • “graceful” means “the program doesn’t just produce wrong effects or blow up! Exceptions--Why?
  • 43. • In traditional procedural programming languages, there were various ways of handling run-time errors. • One way is to return some kind of value indicating whether the procedure succeeded or not. For example: public boolean someMethod( ) { // if this method suceeded, return true // otherwise return false } Note the blurring of the logical distinction between procedures and functions… a bad engineering habit! Exceptions--Traditional Methods
  • 44. • Traditional means of error handling can quickly become ugly, complex and unmanageable. For example: If we intend to do the sequence of calling three procedures followed by one or more instructions, e.g., someMethod( ); someOtherMethod( ); someThirdMethod( ); /* do some intended actions*/ we can find ourselves with code that looks like . . . Exceptions--Traditional Methods
  • 45. if (someMethod( ) == true) { if (someOtherMethod( ) == true) { if (someThirdMethod( ) == true) { // have not encountered errors; do intended actions } else { // handle some error caused by someThirdMethod( ) } } else { // handle some error caused by someOtherMethod( ) } } else { // handle some error caused by someMethod( ) } Exceptions--Traditional Methods
  • 46. int iErrorValue = 0; public void someMethod( ) { // do someMethod’s stuff here // if there is an error, then set iErrorValue = 1 } public void someOtherMethod( ) { // do someOtherMethod’s stuff here // if there is an error, then set iErrorValue = 2 } public void someThirdMethod( ) { // do someThirdMethod’s stuff here // if there is an error, then set iErrorValue = 3 } • Another way error handling is to have the value of a global variable represent the error. Exceptions--Global Variables
  • 47. public void doIt() { someMethod(); someOtherMethod(); someLastMethod(); if (iErrorValue == 1) ... if (iErrorValue == 2) ... if (iErrorValue == 3) ... } But: What if the run-time error stopped us from continuing? For example: What if someMethod( ) failed in such a way that we cannot go on to someOtherMethod( )? To cope, we find ourselves with code that’s nearly as messy as the earlier example which featured multiple nested-ifs: Exceptions--Global Variables
  • 48. public void doit( ) { someMethod( ); if (iErrorValue == 1) { ... } // if else { someOtherMethod( ); if (iErrorValue == 2) { ... } // if else { someThirdMethod( ); if (iErrorValue == 3) { … } // if else { do intended actions } // else } // else }// else Exceptions--Global Variables Note: with this technique we potentially must wrap the ENTIRE program in a series of if/else clauses, duplicating code in places. (Do we prefer robustness or clarity/maintainability?)
  • 49. • As you can see, it gets convoluted very fast even for such a simple sequence of steps. • Historically, the way programmers got around this was simply to not do any error handling at all! • Instead, they generally used one of two approaches: • Upon detecting an error, simply terminate the program, i.e., “recognizethe error but don’t handle it, just quit”, or else … • Don’t even attempt to detect the error; i.e., “let the program react in anarbitrary and unpredictable manner”(blow up? bad values? wrong behavior?) • Both of these violate a basic tenet of structured programming: “Allow only a single point of exit from any procedure or function.” Exceptions: Traditional Approaches
  • 50. Both of these traditional approaches boil down to a case of the programmer simply ignoring the real problem, which is: When a run-time error occurs in a method, • how can we stop the method without allowing it to do any damage? • how can we take appropriate actions to handle the error without having the program simply blow up or do something else that’s bad? It is not acceptable for programs to fail or to do “bad behavior”! • Safety critical programs • Customer satisfaction We require some mechanism to recover from unexpected or abnormal run-time situations. Exceptions: The Real Problem
  • 51. Exception Handling: the modern programming concept for dealing with run-time errors Exception: “a run-time event that may cause a method to fail or to execute incorrectly” Purpose of Exception Handling: “to allow graceful handling of and recovery from run-time errors” Common examples in Java: • NullPointerException • ArithmeticException • ArrayIndexOutOfBoundsException • Java API contains over two dozen exceptions provided by Java. Exceptions and Exception Handling
  • 52. Exception Terminology: • When an exceptional condition occurs, an exception is “thrown” (i.e., the exception has been recognized). • The flow of control is tranferred to the point where the exception is “caught” (I.e., where the exception- handling code responds to it). In the jargon of some other programming languages, when an exception is recognized, an exception is: • “raised” (in place of “thrown”), then • “handled” (in place of “caught”). Same ideas, different jargon. Exceptions: Terminology
  • 53. One is usually more interested in the type of the exception than in manipulating it as an object, so “e” is just an object often thrown away. The general structure of Java’s exception handling: try { // here goes the code that attempts to perform the // intended action, but that could throw an exception ... } // try catch (ExceptionType1 e) { // here goes the code to handle exception type 1 ... } // catch Type1 catch (ExceptionType2 e) { // here goes the code to handle exception type 2 ... } // catch Type2 Exceptions: General Format
  • 54. int iDivisor; int iDividend; float fResult; try { // get input for divisor and dividend ... fResult = (float) iDividend / iDivisor; System.out.println(fResult); } catch (ArithmeticException e) { System.out.println("The divisor was 0"); ... } Exceptions: Simple Example An example showing the structure of Java’s exception handling: See, we don’t Care about the exception, Just about its type being arithmetic error.
  • 55. How Java handles Exceptions: If an exception is thrown in a method, then you can do one of two things in response: 1. Catch the exception right then and there, and handle the exception yourself. You would do this if you have enough information to know how to handle the error. 2. Declare in the method header that whoever called the method has to handle the error. You would do this if you don't have enough information to know how to handle the error. Exceptions: How in Java
  • 56. Given a full Queue, where a client tries to enqueue an item . . . • What should you have the Queue do? • How do you know what it should do? • Should it print out a message? • Should it try to increase the Queue’s size? • Should it not enqueue the item? • Should it dequeue an item to make room for the new item? What should you do? To put it simply, you don't know. Solution: 1. Your design/documentation for enqueue should state a precondition: /** PRE/POST: The queue is not full */ 2. The code will let the exception propagate. Exceptions: Example
  • 57. When an exception is thrown, it must be caught immediately or declared to be allowed to propagate. An example of code that will not compile: class Queue { ... public boolean isEmpty( ) { ... } // isEmpty public void dequeue(Object o) { if (isEmpty( ) == true) throw new QueueEmptyException( ); ... } // dequeue ... } // class Queue Exceptions: Propagation Dequeue is not allowed to do this
  • 58. • Results in an error saying that dequeue must catch or declare QueueEmptyException. • To resolve this, modify dequeue so that the exception is declared to be thrown: public void dequeue(Object o) throws QueueEmptyException { if (isEmpty( ) == true) throw new QueueEmptyException( ); ... } • The method header above declares that this method can throw a QueueEmptyException and that the method calling dequeue( ) must plan on catching the QueueEmptyException. Exceptions: Propagation
  • 59. Suppose you want to use this Queue class to simulate a line of Customers, and you do: class Customer { ... } // Customer class Cashier { Queue customerQueue = new Queue( ); ... public void getNextCustomer( ) { Customer cust; ... cust = (Customer) customerQueue.dequeue( ); ... } // getNextCustomer ... } // Cashier Exceptions: Example
  • 60. This will result in a compile-time error because method getNextCustomer must: • catch exception QueueEmptyException, or • declare that QueueEmptyException propagates upwards Thus, we can repair getNextCustomer in one of two ways: • Option 1: have it catch exception QueueEmptyException • Option 2: have it declare that this method allows QueueEmptyException to propagate Exceptions: Example (cont’d)
  • 61. public void getNextCustomer( ) { Customer cust; try { ... cust = (Customer) customerQueue.dequeue( ); ... } // try catch (QueueEmptyException e) { // handle the QueueEmptyException here ... } // catch } // getNextCustomer An Exception: Catching It Option 1
  • 62. public void getNextCustomer( ) throws QueueEmptyException { Customer cust; ... cust = (Customer) customerQueue.dequeue( ); ... } // getNextCustomer This option dictates that whoever calls method getNextCustomer( ) has the responsibility of handling the exception. An Exception: Declaring that it will propagate Option 2
  • 63. public class Test { public static void A( ) { int array[ ] = new int[5]; try { System.out.println( "In A's try." ); array[ 5 ] = 1; } // try catch( ArrayIndexOutOfBoundsException error ) { System.out.println( "In A's catch." ); } // catch } // A() public static void main( String argv[ ] ) { try { A( ); } // try catch( Exception e ) { System.out.println( "In main's catch." ); } // catch System.out.println( "After try in main." ); } // class Test Exceptions: Another Example Output: In A's try. In A's catch. After try in main. What happens here?
  • 64. • To recognize the exceptional state, use standard if-else logic. • To respond to them, you can create your own Exceptions. Exceptions are objects So you really define your own classes of exception • All Exceptions you create are extensions of java.lang.Exception For example: class QueueEmptyException extends Exception { public QueueEmptyException( ) { } public QueueEmptyException(String strMessage) { super(strMessage); } } Exceptions: Creating Your Own
  • 65. • You can take advantage of inheritance when dealing with exceptions. • Suppose we had an inheritance hierarchy of exceptions like this: • You can have more than one catch block for a try block. • A catch block will only catch that exception or a subclass of that exception. Exception IOException QueueFullException EOFException FileNotFoundException Inheritance and Exceptions
  • 66. try { ... } // try catch (QueueFullException e) { ... } // catch QueueFull Exception catch (FileNotFoundException e) { ... } // catch FileNotFound Exception catch (IOException e) { ... } // catch IO Exception Inheritance and Exceptions This sequence of catches works: Exception IOException QueueFullException EOFException FileNotFoundException
  • 67. try { ... } // try catch (IOException e) { ... } // catch IOException catch (FileNotFoundException e) { ... // this code can never be reached because // FileNotFound is subclass of IOException } // catch FileNotFound Exception This sequence of catches doesn’t work: Inheritance and Exceptions Exception IOException QueueFullException EOFException FileNotFoundException
  • 68. Something you can do with exceptions: try { ... } // try catch (QueueFullException e) { ... } // catch QueueFullException catch (IOException e) { ... } // catch IOException catch (Exception e) { ... // this will catch any other kind of exception // since all exceptions extend Exception } // catch base Exception Inheritance and Exceptions “catch-all” handler
  • 69. • In Java, there are actually two types of Exceptions: • those subclassed from Exception • those subclassed from RuntimeException A technoid annoyance: Both kinds deal with run-time errors • Those subclassed from RuntimeException do not have to be explicitly caught or declared in the method header. • This is good. It prevents code from being cluttered with exception handling: // possible ArrayIndexOutOfBounds customerArray[10] = new Customer( ); // possible ArithmeticException x = y / z; • These may still be caught and/or propagated upwards like normal exceptions. Exception & RuntimeException
  • 70. • There is a problem with the internal state of the program • A contract is violated • A security risk arises (SecurityException) • There is an error with an object or the data it manipulates. • Coping with bad parameters • Dealing with Truly Exceptional conditions (memory, stack). Exceptions: When to Use
  • 71. When to use exceptions: Internal State For example: public int getAge(int iSocialSecurityNumber) throws RecordKeepingException { int index = getHashKey(iSocialSecurityNumber); int iAge = myArray[index].getAge(iSocialSecurityNumber); /* Similar to util.ASSERT( ) statement. */ if (iAge <= 0) throw new RecordKeepingException (“Exception: Age for “ + iSocialSecurityNumber + “ not in range: “ + iAge); else return iAge; }
  • 72. public TreeNode getNodeRecursively (int index, TreeNode currentNode) throws MissingNodeException { if (currentNode == null) { throw new MissingNodeException (“Exception: No node with ” + index + “ found”); } // if else if (currentNode.getNumber() == index) { return currentNode; } // else else if (currentNode.getNumber() > index) { return getNodeRecursively (index, currentNode.getLeftChild()); } // if else { return getNodeRecursively (index, currentNode.getRightChild()); } // else }// getNodeRecursively When to Use Exceptions: Contract Violated
  • 73. public void initializeTreeNode(int iNumberNodes) { if (myTree == null) { if (DEBUG) System.out.println (“Null tree found!”); throw new NullPointerException (“Null tree found”); /* NOTE: Runtime exception; no need to declare propagation */ } else { for (int i=0; i < iNumberNodes; i++) { { TreeNode newNode = new TreeNode( i ); tree.insertNode(newNode); } } } // initializeTreeNode When to Use Exceptions: Error with objects
  • 74. public Integer convertNumber (String strToConvert) { for (int i =0; I < strToConvert.length(); i++) { char chTemp = strToConvert.charAt(i); if (!Character.isDigit(chTemp)) { if (DEBUG) System.out.println (“Bad input String: “ + strToConvert); throw new NumberFormatException(“Exception: “ + strToConvert + “ is not numeric”); } } } // convertNumber When to Use Exceptions: Bad Parameters
  • 75. public class Chat { public static void doStuff() { Listener.count(”Yes it is "); try { Chit.doStuff(); } //try catch (StackOverflowError e){ System.exit(0); } // catch } } // Chat When to Use Exceptions: Truly Exceptional Circumstances public class Chit { public static void doStuff() { Listener.count(”No it isn’t "); try { Chat.doStuff(); } // try catch (StackOverflowError e) { System.exit(0); } // catch } } // Chit public class Listener { static int iCount; public static void count(String strSpeaker){ iCount++; System.out.println (strSpeaker + " is number " + iCount); } } // Listener
  • 76. When to Use Exceptions: Truly Exceptional Circumstances public TreeNode getNode(int index) { TreeNode tempNode; try { tempNode = myTree.getNodeRecursively(new TreeNode(index)); } // try catch(StackOverflowError e) { System.exit(1); } // catch return tempNode; } // getNode Or less obviously
  • 77. • Print an error message • Log the exception • Retry the method (maybe with default parameters) • Restore the system to some previously known "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. When Catching Exceptions you can . . . OOA/OOD/OOP “Who”/what knows enough to handle the exception? local? high-level?
  • 78. Exception Defined: Object that defines an unusual or erroneous situation What to do? Not handle the exception (program halts. Ugh!) Handle the exception where it occurs (try...catch...) Handle the exception at another point in the program (exception propagation) Throwing an exception: Part of the contract of a method (throws) Responsibility of the client to handle (try…catch…) Exceptions: Review
  • 79. A Few Words on Vectors
  • 80. Vectors • An array (list) that dynamically resizes itself to whatever size is needed. • A partial API for Vector: class Vector { public void addElement( Object obj ) public boolean contains(Object elem) public Object elementAt(int index) public Object firstElement() public int indexOf(Object elem) public void insertElementAt(Object obj, int index) public boolean isEmpty() public Object lastElement() public int lastIndexOf(Object elem) public void removeAllElements() public boolean removeElement(Object obj) public void removeElementAt(int index) public void setElementAt(Object obj, int index) public int size() } // of Vector
  • 81. Vectors • Vector is a class. • Must have an object of type Vector instantiated via new( ) to get an instance of Vector. • All rules of good OO programming apply. • Thus, access by requesting services via methods, not via direct access (such an array). size( ) returns current number of elements. elementAt(int index) returns reference to element at specified index. insertElementAt( Object obj, int index ) insertion into linked list (but slower); addElement (Object obj) adds to end. Common Examples
  • 82. Vectors Vectors: • Can be populated only with objects; • Cannot be populated with primitives; • Can be populated with objects that contain primitives; • If you need to populate them with primitives, use type wrapper classes e.g., Integer for int, etc. • Will allow you to populate them with any type of object . . . • Thus, good programming requires that the programmer enforce typing within a Vector, because Java doesn’t.
  • 83. Vectors Vectors and casting: • Vectors are a subclass of class Object. • Thus, vectors can handle any class of object (i.e., no type checking) • Thus, must cast any object obtained from a Vector before invoking any methods not defined in class Object. Vector v = new Vector ( ); Student s = new Student( “Joe” ); Student otherStudent; v.addElement( s ); otherStudent = (Student) v.elementAt(0);
  • 84. // Assume we have vector v and int k. // Assume int k is an index within the // range [0..(v.size( ) - 1)]. Object o; o = v.elementAt(k); // no cast needed, already Object if (o instanceof Student) { // do stuff for Student } if (o instanceof Cafeteria) { // do stuff for Cafeteria } Vectors Vectors and instanceof: Design issue: This example is legal Java, but is it good programming?
  • 85. Vectors and Arrays Arrays: statically sized Vectors: dynamically sized Arrays: can directly access, e.g., myArray[6] but shouldn’t (except maybe within the class in which they’re declared IF efficiency concerns; or for testing purposes.) Vectors: must use methods to access. Vector services provide a good model for the Array services you should implement.
  • 86. Vectors versus Linked Lists Can use Vectors to simulate a Linked List: • Don’t want direct access to data, so . . . • Provide methods for getPrevious( ), getNext( ), etc. that do the std. Linked List things. • While the list is implemented as a Vector, the client uses it as if it’s a Linked List. BUT . . . There are performance implications (that may or may not matter for a given instance). What is the cost of: • insertion? • deletion?
  • 87. Vectors versus Linked Lists For ordered Linked Lists: • cost of traversal to locate target: O(N) • cost of insert/delete: O(1) • total cost: O(N) For ordered Vector: • cost of traversal to locate target: O(N) (if accessible via direct access, then O(1) ) • insertion or deletion of element implies (average case), moving O(N) elements • total cost: O(N) Thus, at first glance, equivalent… But what does Big Oh hide here? • Linked Lists: search thru N/2, plus insert/delete • Vectors: search thru N/2, plus moving N/2 Thus, Vectors imply twice the work
  • 88. Vector Capacity • Capacity is dynamic • Capacity can grow and shrink to fit needs • Capacity grows upon demand • Capactiy shrinks when you tell it to do so via method trimToSize( ) • Using trimToSize( ) implies performance costs upon subsequent insertion. • When extra capacity is needed, then it grows by how much? • Depends on which of three constructors is used . . .
  • 89. Vector Capacity Three Vector constructors: • public Vector (int initialCapacity, int capacityIncrements); • public Vector (int initialCapacity); • public Vector( ); First constructor (2 parameters): • begins with initialCapacity • if/when it needs to grow, it grows by size capacityIncrements. Second constructor( 1 parameter): • begins with initialCapacity • if/when needs to grow, it grows by doubling current size. Third construtor (no parameters): • begins with capacity of 10 • if/when needs to grow, it grows by doubling current size.

Editor's Notes