A reference object has one or more modifiable fields. (More on this later.)
A document has a title and content. Both can be modified. The title can change, words can be added to and removed from the content.
Here's a class diagram for Document:
In Eclipse we can add a new class to a project using the New java Class dialog:
Note that we added Serializable to the implemented interfaces. Serializable objects can be saved to files and read from files:
ObjectOutputStream os = null;
Document doc = new Document();
try {
os = new ObjectOutputStream(new FileOutputStream("essay"));
os.writeObject(doc);
}
} catch(Exception e) {
}
ObjectInputStream is = null;
try {
is = new ObjectInputStream(new
FileInputStream("essay"));
doc = (Envelope)is.readObject();
} catch(Exception e) {
}
Eclipse offers to add a version field. This number will be saved to output files during serialization. If it differs from the version number when the file is read later, then the JVM will know that the document is obsolete.
We add two more fields corresponding to title and content:
import java.io.Serializable;
import java.util.Collection;
/**
* @author pearce
*
*/
public class Document implements
Serializable {
private static final long serialVersionUID =
1L;
private String title;
private Collection<String> content;
}
Note that the content field is a collection from Java's Collections Framework. Collections are easier to manage than arrays.
Next, we generate the principle constructor using Eclipse's "Generate Constructor" dialog:
We also add a derived constructor:
import
java.io.Serializable;
import java.util.Collection;
import java.util.LinkedList;
/**
* @author pearce
*
*/
public class
Document implements Serializable {
private
static final
long serialVersionUID
= 1L;
private
String title;
private
Collection<String> content;
/**
* Initializes this document
* @param
title the
title of this document
*/
public
Document(String title) {
super();
this.title = title;
content
= new LinkedList<String>();
}
/**
* Initializes this document with default title
*/
public
Document() {
this("My Document");
}
}
It's a good idea to have a parameterless constructor. Many places in Java assume that such a constructor exists.
For example, the following code won't compile unless Document has a parameterless constructor:
class Letter extends Document {
public Letter() {
super();
}
// etc.
}
Fields that aren't collections should have getter and setter methods. We can use Eclipse's Generate Getters and Setters dialog to create them:
Here's the code so far:
public class
Document implements Serializable {
private static final long serialVersionUID =
1L;
private String title;
private
Collection<String> content;
/**
* Initializes this document
* @param title the title of this document
*/
public
Document(String title) {
super();
this.title = title;
content = new
LinkedList<String>();
}
/**
* Initializes this document with default title
*/
public Document() {
this("My Document");
}
/**
* @return the title
*/
public String
getTitle() {
return title;
}
/**
* @param title the title to set
*/
public void setTitle(String
title) {
this.title = title;
}
}
For collection fields, we generate methods that delegate to the collection's methods. We can use Eclipse's Generate Delegate Methods dialog for this:
Here's the code:
public class Document
implements Serializable {
private static final long serialVersionUID =
1L;
private String title;
private
Collection<String> content;
/**
* Initializes this document
* @param title the title of this document
*/
public
Document(String title) {
super();
this.title = title;
content = new
LinkedList<String>();
}
/**
* Initializes this document with default title
*/
public Document() {
this("My Document");
}
/**
* @return the title
*/
public String
getTitle() {
return title;
}
/**
* @param title the title to set
*/
public void setTitle(String
title) {
this.title = title;
}
/**
* @param e
* @return
* @see java.util.Collection#add(java.lang.Object)
*/
public boolean add(String
e) {
return content.add(e);
}
/**
* @return
* @see java.util.Collection#iterator()
*/
public
Iterator<String> iterator() {
return content.iterator();
}
/**
* @param o
* @return
* @see java.util.Collection#remove(java.lang.Object)
*/
public boolean
remove(Object o) {
return content.remove(o);
}
/**
* @return
* @see java.util.Collection#size()
*/
public int size() {
return content.size();
}
}
Here's an example of how we could print each word in the content of a document on a single line:
Iterator<String> p = doc.iterator();
while
(p.hasNext()) {
System.out.println(p.next());
}