Java Reference
In-Depth Information
Section 9.4 created a class hierarchy, in which class
BasePlusCommissionEmployee
inher-
ited from
CommissionEmployee
. The examples in that section manipulated
Commission-
Employee
and
BasePlusCommissionEmployee
objects by using references to them to
invoke their methods—we aimed superclass variables at superclass objects and subclass
variables at subclass objects. These assignments are natural and straightforward—super-
class variables are
intended
to refer to superclass objects, and subclass variables are
intended
to refer to subclass objects. However, as you'll soon see, other assignments are possible.
In the next example, we aim a
superclass
reference at a
subclass
object. We then show
how invoking a method on a subclass object via a superclass reference invokes the
subclass
functionality—the type of the
referenced object
,
not
the type of the
variable
, determines
which method is called. This example demonstrates that
an object of a subclass can be treated
as an object of its superclass,
enabling various interesting manipulations. A program can create
an array of superclass variables that refer to objects of many subclass types. This is allowed
because each subclass object
is an
object of its superclass. For instance, we can assign the
reference of a
BasePlusCommissionEmployee
object to a superclass
CommissionEmployee
variable, because a
BasePlusCommissionEmployee
is a
CommissionEmployee
—so we can
treat a
BasePlusCommissionEmployee
as a
CommissionEmployee
.
As you'll learn later in the chapter, you
cannot treat a superclass object as a subclass
object,
because a superclass object is
not
an object of any of its subclasses. For example, we
cannot assign the reference of a
CommissionEmployee
object to a subclass
BasePlusCom-
missionEmployee
variable, because a
CommissionEmployee
is
not
a
BasePlusCommission-
Employee
—a
CommissionEmployee
does
not
have a
baseSalary
instance variable and does
not
have methods
setBaseSalary
and
getBaseSalary
. The
is-a
relationship applies only
up the hierarchy
from a subclass to its direct (and indirect) superclasses, and
not
vice versa
(i.e., not down the hierarchy from a superclass to its subclasses or indirect subclasses).
The Java compiler
does
allow the assignment of a superclass reference to a subclass
variable if we explicitly
cast
the superclass reference to the subclass type. Why would we
ever want to perform such an assignment? A superclass reference can be used to invoke
only
the methods declared in the superclass—attempting to invoke
subclass-only
methods
through a superclass reference results in compilation errors. If a program needs to perform
a subclass-specific operation on a subclass object referenced by a superclass variable, the
program must first cast the superclass reference to a subclass reference through a technique
known as
downcasting
. This enables the program to invoke subclass methods that are
not
in the superclass. We demonstrate the mechanics of downcasting in Section 10.5.
Software Engineering Observation 10.3
Although it's allowed, you should generally avoid downcasting.
The example in Fig. 10.1 demonstrates three ways to use superclass and subclass vari-
ables to store references to superclass and subclass objects. The first two are straightfor-
ward—as in Section 9.4, we assign a superclass reference to a superclass variable, and a
subclass reference to a subclass variable. Then we demonstrate the relationship between
subclasses and superclasses (i.e., the
is-a
relationship) by assigning a subclass reference to a
superclass variable. This program uses classes
CommissionEmployee
and
BasePlusCommis-
sionEmployee
from Fig. 9.10 and Fig. 9.11, respectively.