Java Reference
In-Depth Information
EXAMPLE:
A Person Class
It is common to have instance variables of a class type. The class
Person
defined in
Display 5.19 has two instance variables of type
Date
. So, the class
Person
has instance
variables of a class type. (The class
Date
was defined in Chapter 4 , Display 4.11. We
have reproduced the relevant portions of the date class definition in Display 5.20 .)
In fact, all the instance variables for the class
Person
are of class types. An object
of the class
Person
has the basic data about people that is found in such places as
on tombstones and in author listings in library catalogues. It describes a person by
giving the person's name, date of birth, and date of death. If the person is still alive,
then the value
null
is used as the date of death. (So
null
is good.) A simple program
illustrating the class
Person
is given in Display 5.21. We will discuss a few details
about the class
Person
here, but most of the various methods in the class
Person
will
be discussed as we cover the corresponding topic in the following subsections.
Normally, a class definition should include a no-argument constructor. However,
there are cases where a no-argument constructor makes little sense. For example, the
wrapper classes such as
Integer
and
Double
do not have no-argument constructors, as
we explained in the Pitfall subsection “A Wrapper Class Does Not Have a No-Argument
Constructor,” which appeared earlier in this chapter. The class
Person
also does not
have a no-argument constructor for a reason. A person may have no date of death,
but a person always has a date of birth. A no-argument constructor should initialize all
instance variables, but there is no suitable value to initialize the instance variable
born
unless it is provided as an argument to the constructor. In particular, it makes no sense
to initialize the instance variable
born
to
null
; that would indicate that the person
was never born. It makes little sense to have a person who was never born, so it makes
little sense to have a no-argument constructor for the class
Person
. Note that because
we defined some constructors for the class
Person
but did not define a no-argument
constructor, it follows that the class
Person
does not have a no-argument constructor.
Since we are assuming that an object of the class
Person
always has a birth date
(which is not
null
), the following should always be true of an object of the class
Person
:
An object of the class
Person
has a date of birth (which is not
null
), and if the object
has a date of death, then the date of death is equal to or later than the date of birth.
If you check the definition of the class
Person
, you will see that this statement
is always true. It is true of every object created by a constructor, and all the other
methods preserve the truth of this statement. In fact, the private method
consistent
was designed to provide a check for this property. A statement, such as the above,
that is always true for every object of the class is called a
class invariant
.
Note that the definition of
equals
for the class
Person
includes an invocation
of
equals
for the class
String
and an invocation of the method
equals
for the
class
Date.
Java determines which
equals
method is being invoked from the type
of its calling object. Because the instance variable
name
is of type
String
, the
invocation
name.equals(...)
is an invocation of the method
equals
for the class
String
. Because the instance variable
born
is of type
Date
, the invocation
born.
equals(...)
is an invocation of the method
equals
for the class
Date
.
Similarly, the definition of the method
toString
for the class
Person
includes
invocations of the method
toString
for the class
Date
.