Java Reference
In-Depth Information
}
class
Circle
extends
Shape
{
public
static
final
double
PI
=
3.14159265358979323846
;
protected
double
r
;
// Instance data
public
Circle
(
double
r
)
{
this
.
r
=
r
;
}
// Constructor
public
double
getRadius
()
{
return
r
;
}
// Accessor
public
double
area
()
{
return
PI
*
r
*
r
;
}
// Implementations of
public
double
circumference
()
{
return
2
*
PI
*
r
;
}
// abstract methods.
}
class
Rectangle
extends
Shape
{
protected
double
w
,
h
;
// Instance data
public
Rectangle
(
double
w
,
double
h
)
{
// Constructor
this
.
w
=
w
;
this
.
h
=
h
;
}
public
double
getWidth
()
{
return
w
;
}
// Accessor method
public
double
getHeight
()
{
return
h
;
}
// Another accessor
public
double
area
()
{
return
w
*
h
;
}
// Implementation of
public
double
circumference
()
{
return
2
*(
w
+
h
);
}
// abstract methods
}
Each
abstract
method in
Shape
has a semicolon right after its parentheses. They
have no curly braces, and no method body is defined. Using the classes defined in
Example 3-5
, we can now write code such as:
Shape
[]
shapes
=
new
Shape
[
3
];
// Create an array to hold shapes
shapes
[
0
]
=
new
Circle
(
2.0
);
// Fill in the array
shapes
[
1
]
=
new
Rectangle
(
1.0
,
3.0
);
shapes
[
2
]
=
new
Rectangle
(
4.0
,
2.0
);
double
totalArea
=
0
;
for
(
int
i
=
0
;
i
<
shapes
.
length
;
i
++)
totalArea
+=
shapes
[
i
].
area
();
// Compute the area of the shapes
Notice two important points here:
• Subclasses of
Shape
can be assigned to elements of an array of
Shape
. No cast is
necessary. This is another example of a widening reference type conversion
(discussed in
Chapter 2
).
• You can invoke the
area()
and
circumference()
methods for any
Shape
object, even though the
Shape
class does not define a body for these methods.
When you do this, the method to be invoked is found using virtual method
lookup, which means that the area of a circle is computed using the method
defined by
Circle
, and the area of a rectangle is computed using the method
defined by
Rectangle
.