|
|||||
Web
Design & Development CS506
VU
Lesson
9
Modification
of Address Book Code
Adding
Persistence Functionality
Hopefully,
your address book you
built previously is giving
you the required results except one
i.e.
persistence.
You might have noticed that
after adding some person
records in the address book; if
you
exit
form the program next time
on re-executing address book
all the previous records are
no more
available.
To overcome the
above problem, we will
modify our program so that
on exiting/starting of address
book,
all the previously added
records are available each
time. To achieve this, we have to provide
the
persistence
functionality. Currently, we will
accomplish this task by saving
person records in some
text
file.
Supporting
simple persistence by any
application requires handling of
two scenarios. These
are
On
start up of application data
(person records ) must be read
from file
On
end/finish up of application data
(person records) must be
saved in file
To support
persistence, we have to handle the above
mentioned scenarios
Scenario
1 Start Up
Establish a
data channel with a file by
using streams
Start
reading data (person records)
from file line by
line
Construct
PersonInfo objects from each line
you have read
Add
those PersonInfo objects in arraylist
persons.
Close
the stream with the
file
Perform
these steps while
application is loading up
We
will read records from a
text file named persons.txt.
The person records will be
present in the file in
the
following format.
Ali,defence,9201211
Usman,gulberg,5173940
Salman,LUMS,5272670
persons.txt
As
you have seen, each person
record is on a separate line. Person's
name, address &
phone number is
separated using comma
(,).
We
will modify our
AddressBook.java by adding a new method
loadPersons into it. This
method
will
provide the implementation of all the
steps. The method is shown
below:
public
void loadPersons ( ){
String
tokens[] = null;
String
name, add, ph;
65
Web
Design & Development CS506
VU
try
{
FileReader fr =
new FileReader("persons.txt");
BufferedReader br
= new BufferedReader(fr);
String
line = br.readLine();
while
( line != null ) {
tokens
= line.split(",");
name
= tokens[0];
add =
tokens[1];
ph =
tokens[2];
PersonInfo
p = new PersonInfo(name, add,
ph);
persons.add(p);
line
= br.readLine();
}
br.close();
fr.close();
}catch(IOException
ioEx){
System.out.println(ioEx);
}
}
First,
we have to connect with the text
file in order to read line by
line person records from
it. This
task
is accomplished with the following lines
of code
FileReader fr =
new FileReader("persons.txt"); BufferedReader br =
new
BufferedReader(fr);
FileReader is a
character based (node)
stream that helps us in reading
data in the form of
characters.
As we are using streams, so we have to
import the java.io package in
the
AddressBook
class.
We
passed the file name
persons.txt to the constructor of the
FileReader.
Next
we add BufferedReader (filter stream) on
top of the FileReader because
BufferedReader
facilitates
reading data line by line.
(As you can recall
from the lecture that
filter streams are
attached
on top of node streams).
That's why the constructor of BufferedReader is
receiving the
fr the
FileReader object.
The
next line of code will
read line from file by using
readLine( ) method of
BufferedReader and
save it in a string variable
called line.
String
line = br.readLine( );
After
that while loop starts.
The condition of while loop
is used to check whether the
file is reached
to end (returns
null) or not. This loop is
used to read whole file
till the end. When end comes
(null),
this
loop will finish.
66
Web
Design & Development CS506
VU
while
(line != null)
Inside
loop, the first step we
performed is tokenizing the string.
For this purpose, we have
used
split
method of String class. This method
returns substrings (tokens) according to
the regular
expression or
delimiter passed to
it.
tokens
= line.split(",");
The
return type of this method is
array of strings that's why we
have declared tokens as a
String
array
in the beginning of this method as
String
tokens[];
For
example, the line contains the following
string
Ali,defence,9201211
Now
by calling split(",") method on this
string, this method will
return back three substrings ali
defence
and
9201211
because
the delimiter we have passed to it is
comma. The delimiter
itself
is
not included in the substrings or
tokens.
The
next three lines of code are
simple assignments statements.
The tokens[0] contains the
name
of the
person because the name is always in the
beginning of the line, tokens[1] contains
address
of the
person and tokens[2] contains the phone
number of the person.
name
= tokens[0];
add =
tokens[1];
ph =
tokens[2];
The
name, add and ph are of type
String and are declared in the beginning
of this method.
After
that we have constructed the object of
PersonInfo class by using parameterized
constructor
and
passed all these strings to
it.
PersonInfo
p = new PersonInfo(name, add, ph);
Afterward
the PersonInfo object's p is added to the
arraylist i.e. persons.
persons.add(p);
The
last step we have done inside loop is
that we have again read a
line form the file by using
the
readLine()
method.
By
summarizing the task of while
loop we can conclude that it
reads the line from a
file,
tokenizethat
line into three substrings
followed by constructing the PersonInfo
object by
using
these tokens. And adding
these objects to the arraylist. This
process continues till the
file
reaches
its end.
The
last step for reading
information from the file is
ordinary one closing the
streams,
because
files are external
resources, so it's better to close
them as soon as possible.
Also
observe that we used
try/catch block because
using streams can result in
raising exceptions
that
falls under the checked exceptions category
that needs mandatory
handling.
The
last important step you have to
perform is to call this method
while loading up. The
most
67
Web
Design & Development CS506
VU
appropriate
place to call this method is
from inside the constructor of
AddressBook.java. So
the constructor
will now look like
similar to the one given
below:
..................
public
AddressBook () {
Persons
= new ArrayList();
loadPersons();
}
..................
AddressBook.java
Scenario
2 End/Finish Up
Establish a
datachanel(stream) with a file by
using streams
Take
out PersonInfo objects from ArrayList
(persons)
Build
a string for each PersonInfo
object by inserting commas
(,) between name
&
address and address & phone
number.
Write
the constructed string to the
file
Close
the connection with
file
Perform
these steps while exiting
from address book.
Add
another method savePersons
into AddressBook.java.
This method will
provide
the
implementation
of all the above mentioned
steps. The method is shown
below:
Public
void savePersons ( ){
try
{
PersonInfo
p;
String
line;
FileWriter
fw = new
FileWriter("persons.txt");
PrintWriter
pw = new PrintWriter(fw);
for(int
i=0; i<persons.size();
i++)
{
p =
(PersonInfo)persons.get(i);
line
= p.name +","+ p.address
+","+ p.phoneNum;
// writes
line to file (persons.txt)
pw.println(line);
}
pw.flush();
pw.close();
68
Web
Design & Development CS506
VU
fw.close();
}catch(IOException
ioEx){
System.out.println(ioEx);
}
}
As
you can see, that we have
opened the same file (persons.txt) again
by using a set of
streams.
After
that we have started for
loop to iterate over arraylist as we
did in
searchPerson
and deletePerson methods.
Inside
for loop body, we have taken
out PersonInfo object and
after type casting it we have assigned
its
reference to a
PersonInfo type local
variable p. This is achieved by the help
of following line of
code
p =
(PersonInfo)persons.get(i);
Next
we build a string and insert
commas between the PersonInfo attributes
and assign the newly
constructed
string to string's local
variable line as shown in the
following line of
code.
line
= p.name +","+ p.address
+","+ p.phoneNum;
Note:
Since, we
haven't declare PersonInfo attributes
private, therefore we are
able to directly
access
them
inside AddressBook.java.
The
next step is to write the
line representing one PersonInfo
object's information, to the file.
This
is done by
using println method of PrintWriter as
shown below
pw.println(line);
After
writing line to the file, the
println method will move the
cursor/control to the next
line.
That's
why each line is going to be
written on separate
line.
The
last step for saving
information to the file is ordinary one
closing the streams but
before
that
notice the code line that
you have not seen/performed while
loading persons records from
file.
That
is
pw.flush(
);
The
above line immediately flushes
data by writing any buffered
output/data to file. This
step is
necessary
to perform or otherwise you will
most probably lose some
data for the reason
that
PrintWriter
is a Buffered Stream and
they have their own internal
memory/storage capacity for
efficiency
reasons. Buffered Streams do
not send the data until
their memory is full.
Also
we have written this code
inside try-catch
block.
The
last important step you have to
perform is to call this method
before exiting from the
address
book.
The most appropriate place to
call this method is under
case 4
(exit
scenario) in Test.java. So the case 4 will
now look like similar to the
one given below:
69
Web
Design & Development CS506
VU
case
4:
ab.savePersons();
System.exit(0);
Test.java
Compile
& Execute
Now
again after compiling all
the classes, run the Test
class. Initially we are
assuming that out
persons.txt
file is empty, so our
arraylist persons will be
empty on the first start up of
address book.
Now
add some records into
it, perform search or delete operations.
Exit from the address
book
by choosing
option 4. Check out the
persons.txt file. Don't get surprised by
seeing that it
contains
all the person records in the
format exactly we have seen
above.
Next
time you will run the
address book; all the
records will be available to
you. Perform the search
or
delete
operation to verify
that.
Finally
You have done it !!!
References
Example
code, their explanations and
corresponding figures for this
handout are taken from the
book
JAVA A
Lab Course by Umair Javed.
This material is available
just for the use of VU
students of the
course
Web Design and Development and
not for any other commercial
purpose without the consent
of
author.
Abstract
Classes and Interfaces
Problem
and Requirements
Before
moving on to abstract classes,
first examine the following
class hierarchy shown
below:
Circle
Square
·
Suppose
that in order to exploit
polymorphism, we specify that
2-D objects must be able
to
compute
their area.
All
2-D classes must respond to
area() message.
·
How
do we ensure that?
Define area method in class
Shape
Force the subclasses of Shape to
respond area()
message
·
Java's
provides us two solutions to
handle such problem
Abstract Classes
Interfaces
70
Web
Design & Development CS506
VU
Abstract
Classes
Abstract
classes are used to define
only part of an implementation.
Because, information is
not
complete
therefore an abstract class cannot be
instantiate. However, like
regular classes, they
can
also
contain instance variables and
methods that are full
implemented. The class that
inherits from
abstract
class is responsible to provide
details.
Any
class with an abstract method (a method
has no implementation similar to
pure virtual
function
in C++) must be declared abstract,
yet you can declare a class
abstract
that
has no abstract
method.
If
subclass overrides all
abstract methods of the super
class, than it becomes a
concrete (a class
whose
object
can be instantiate) class
otherwise we have to declare it as abstract or we
can not compile
it.
The
most important aspect of
abstract class is that reference of an
abstract class can point to
the object of
concrete
classes.
Code
Example of Abstract
Classes
The
Shape
class
contains an abstract method calculateArea()
with no definition.
public
abstract
class
Shape{
public
abstract
void
calculateArea();
}
Class
Circle
extends
from abstract Shape class,
therefore to become concrete
class it must
provides
the
definition of calculateArea()
method.
public
class Circle
extends
Shape {
private
int x, y;
private
int radius;
public
Circle() {
x =
5;
y =
5;
radius =
10;
}
//
providing definition of abstract
method
public
void calculateArea
()
{
double
area = 3.14 * (radius * radius);
System.out.println("Area:
" + area);
}
}//end
of class
The
Test class contains main method.
Inside main, a reference s of
abstract Shape class is
created. This
reference
can point to Circle
(subclass of abstract class
Shape) class object as it is a
concrete class.
With
the help of reference, method calculateArea()
can be invoked of Circle
class. This is all
shown
in the
form of code below
public
class Test
{
71
Web
Design & Development CS506
VU
public
static void main(String
args[]){
//can
only create references of
A.C.
Shape
s = null;
//Shape
s1 = new Shape(); //cannot instantiate
//abstractclass
reference can point to
concrete subclass
s =
new Circle();
s.calculateArea();
}
}//end
of class
The
compilation and execution of the above
program is shown below:
Interfaces
As we
seen one possible java's
solution to problem discussed in
start of the tutorial. The
second possible
java's
solution is Interfaces.
Interfaces
are special java type which
contains only a set of method prototypes,
but doest not
provide
the
implementation for these prototypes. All
the methods inside an interface are
abstract by default
thus
an
interface is tantamount to a pure
abstract class a class
with zero implementation.
Interface can
also
contains static final
constants
Defining an
Interface
Keyword
interface is used instead of class as
shown below:
public
interface
Speaker{
public
void speak();
}
Implementing
(using) Interface
Classes
implement
interfaces.
Implementing an interface is like
signing
a contract. A
class that
implements an
interface will have to provide the
definition of all the methods
that are present
inside
72
Web
Design & Development CS506
VU
an
interface. If the class does
not provide definitions of
all methods, the class would
not compile.
We have to declare
it as an abstract class in order to get
it compiled.
Relationship
between a class and interface is
equivalent to "responds
to" while
"is
a"
relationship
exists in inheritance.
Code
Example of Defining & Implementing an
Interface
The
interface Printable
contains
print() method.
public
interface
Printable{
public
void print();
}
Class
Student
is
implementing the interface Printable.
Note the use of keyword implements
after
the
class
name. Student class has to
provide the definition of print method or
we are unable to
compile.
The
code snippet of student class is
given below:
public
class Student
implements Printable
{
private
String name;
private
String address;
public
String toString () {
return
"name:"+name +" address:"+address;
}
//providing
definition of interface's print
method
public
void print() {
System.out.println("Name:"
+name+" address"+address);
}
}//end
of class
Interface
Characteristics
Similar
to abstract class, interfaces imposes a
design structure on any class that
uses the interface.
Contrary
to inheritance, a class can
implement more than one interfaces. To do
this separate the
interface
names with comma. This is
java's way of multiple
inheritance.
class
Circle implements Drawable , Printable {
.......... }
Objects
of interfaces also cannot be
instantiated.
Speaker
s = new Speaker(); // not compile
However,
a reference of interface can be created
to point any of its
implementation class. This
is
interface
based polymorphism.
Code
Example: Interface based
polymorphism
Interface
Speaker is implemented by three classes
Politician, Coach and Lecturer. Code
snippets of all
these
three classes are show
below:
73
Web
Design & Development CS506
VU
public
class Politician
implements
Speaker{
public
void speak(){
System.out.println("Politics
Talks");
}
}
public
class Coach
implements
Speaker{
public
void speak(){
System.out.println("Sports
Talks");
}
}
public
class Lecturer
implements
Speaker{
public
void speak(){
System.out.println("Web
Design and Development
Talks");
}
}
As usual,
Test class contains main method.
Inside main, a reference sp is created of
Speaker class.
Later,
this reference is used to point to the
objects of Politician, Coach and Lecturer
class. On calling
speak
method with the help of sp,
will invoke the method of a class to
which sp is pointing.
public
class Test{
public
static void main (String
args[ ]) {
Speaker
sp = null;
System.out.println("sp
pointing to Politician");
sp = new
Politician();
sp.speak();
System.out.println("sp
pointing to Coach");
sp = new
Coach();
sp.speak();
System.out.println("sp
pointing to Lecturer");
sp = new
Lecturer();
sp.speak();
}
}
The
compilation and execution of the above
program is shown below:
74
Web
Design & Development CS506
VU
References
Example
code, their explanations and
corresponding figures for this
handout are taken from the
book
JAVA A
Lab Course by Umair Javed.
This material is available
just for the use of VU
students of the
course
Web Design and Development and not
for any other
commercial
purpose
without the
consent
of author.
75
Table of Contents:
|
|||||