Even if an application doesn't require fields to be read-only, making fields private and adding methods to set
and fetch them enables you to add actions that may be needed in the future. If programmers can access a
class's fields directly, you have no control over the values they will use or what happens when values are
changed. Additionally, making a field part of the contract of a class locks in the implementation of that
classyou can't change the implementation without forcing all clients to be recompiled. For example, a future
version of Body may want to look-up the ID number in a database indexed by the body's name and not
actually store the ID number in the object at all. Such a change cannot be made if idNum is accessible to
clients. For these reasons, you will see very few public or protected fields in subsequent examples in
this book.
Methods to get or set a value in an object's state are sometimes said to define a property of that object. For
example, the Body class's getID can be said to define an ID property for Body objects that is retrieved by
the getID method, and implemented by the idNum field. Some automatic systems, including those for the
JavaBeans™ component architecture, use these conventions to provide automatic property manipulation
systems; see Section 25.3 on page 721. We can and should define the name and orbits fields to be
properties by making them private and providing set and get methods for them:
class Body {
private long idNum;
private String name = "
private Body orbits = null;
private static long nextID = 0;
// constructors omitted ...
public long getID() { return idNum; }
public String getName() { return name; }
public void setName(String newName) {
name = newName;
}
public Body getOrbits() { return orbits; }
public void setOrbits(Body orbitsAround) {
orbits = orbitsAround;
}
}
Making a field final can be another way to prevent unwanted modifications to a field, but immutability and
accessibility should not be confused. If a field is immutable then it should be declared final regardless of
accessibility. Conversely, if you don't want a field to form part of the contract of a class you should hide it
behind a method, regardless of whether the field is read-only or modifiable.
Now that we have made all the fields of Body private, we can return to an earlier remark that access control is
per-class not per-object. Suppose that a body could be captured by another body and forced to orbit around it,
we could define the following method in Body:
public void capture(Body victim) {
victim.orbits = this;
}
If access control were per-object, then the capture method when invoked on one object would not be able
to access the private orbits field of the victim body object to modify it. But because access control is
per-class, the code of a method in a class has access to all the fields of all objects of that classit simply needs a
reference to the object, such as via a parameter as above. Some object-oriented languages advocate per-object
access control, but the Java programming language is not one of them.