Java Reference
In-Depth Information
double
myPrice
)
{
burrito
=
toDecorate
;
price
=
myPrice
;
}
public
final
double
getPrice
()
{
return
(
burrito
.
getPrice
()
+
price
);
}
}
The combination of an
abstract
base,
BurritoOptional
Extra
, and a
protected
constructor means that the only valid
way to get a
BurritoOptionalExtra
is to construct an
instance of one of the subclasses, as they have public construc‐
tors (which also hide the setup of the price of the component
from client code).
Let's test the implementation out:
Burrito
lunch
=
new
Jalapeno
(
new
Guacamole
(
new
SuperBurrito
()));
// The overall cost of the burrito is the expected $8.09.
System
.
out
.
println
(
"Lunch cost: "
+
lunch
.
getPrice
());
The decorator pattern is very widely used—not least in the JDK utility classes.
When we discuss Java I/O in
Chapter 10
, we will see more examples of decorators in
the wild.
O
n
Field Inheritance and Accessors
Java offers multiple potential approaches to the design issue of the inheritance of
state. The programmer can choose to mark fields as
protected
and allow them to
be accessed directly by subclasses (including writing to them). Alternatively, we can
provide
accessor methods
to read (and write, if desired) the actual object fields, while
retaining encapsulation, and leaving the fields as
private
.
Let's revisit our earlier
PlaneCircle
example from the end of
Chapter 9
and explic‐
itly show the field inheritance:
public
class
Circle
{
// This is a generally useful constant, so we keep it public
public
static
final
double
PI
=
3.14159
;
protected
double
r
;
// State inheritance via a protected field
// A method to enforce the restriction on the radius
protected
void
checkRadius
(
double
radius
)
{
if
(
radius
<
0.0
)
throw
new
IllegalArgumentException
(
"radius may not < 0"
);
}
// The non-default constructor