Java Reference
In-Depth Information
This may not be desirable. Suppose
NumParts
is meant to count the number of objects created from
Part
. Any
outside class can set it to any value it pleases, so the writer of the class
Part
cannot guarantee that it will always reflect
the number of objects created.
An instance variable, as always, can be accessed via an object only. When a user class creates an object
p
of
type
Part
, it can use
p.price
(or
p.name
) to refer directly to the instance variable and can change it, if desired, with
a simple assignment statement. There is nothing to stop the user class from setting the variable to an unreasonable
value. For instance, suppose that all prices are in the range 0.00 to 99.99. A user class can contain the following
statement, compromising the integrity of the price data:
p.price = 199.99;
To solve these problems, we must make the data fields
private
; we say we must
hide
the data. We then provide
public
methods for others to set and retrieve the values in the fields. Private data and public methods are the essence
of
data encapsulation
. Methods that set or change a field's value are called
mutator
methods. Methods that retrieve
the value in a field are called
accessor
methods.
Let's show how the two problems mentioned can be solved. First, we redefine the fields as
private
:
public class Part {
private static int NumParts = 0; // class variable
private String name; // instance variable
private double price; // instance variable
}
Now that they are
private
, no other class has access to them. If we want
NumParts
to reflect the number of
objects created from the class, we would need to increment it each time a constructor is called. We could, for example,
write a no-arg constructor as follows:
public Part() {
name = "NO PART";
price = -1.0; // we use -1 since 0 might be a valid price
NumParts++;
}
Whenever a user class executes a statement such as the following, a new
Part
object is created
and
1
is added
to
NumParts
:
Part p = new Part();
Hence, the value of
NumParts
will always be the number of
Part
objects created. Further, this is the
only
way to
change its value; the writer of the class
Part
can guarantee that the value of
NumParts
will always be the number of
objects created.
Of course, a user class may need to know the value of
NumParts
at any given time. Since it has no access to
NumParts
, we must provide a
public accessor method
(
GetNumParts
, say; we use uppercase
G
for a static accessor, since
it provides a quick way to distinguish between static and non-static), which returns the value. Here is the method:
public static int GetNumParts() {
return NumParts;
}
The method is declared
static
since it operates only on a
static
variable and does not need an object
to be invoked. It can be called with
Part.GetNumParts()
. If
p
is a
Part
object, Java allows you to call it with
p.GetNumParts()
. However, this tends to imply that
GetNumParts
is an instance method (one that is called via an
Search WWH ::
Custom Search