Java Reference
In-Depth Information
When we loop through the elements of this array, we don't have to know or care
whether the element is actually a
Circle
or an
Ellipse
. What we do care about very
much, however, is that the correct value is computed when we invoke the
area()
method of any element of the array. In other words, we don't want to use the for‐
mula for the area of a circle when the object is actually an ellipse!
All we really want is for the objects we're computing the areas of to “do the right
thing”—the
Circle
objects to use their definition of how to compute their own
area, and the
Ellipse
objects to use the definition that is correct for them.
Seen in this context, it is not surprising at all that method overriding is handled dif‐
ferently by Java than is field hiding.
m
g
Virtual method lookup
If we have a
Circle[]
array that holds
Circle
and
Ellipse
objects, how does the
compiler know whether to call the
area()
method of the
Circle
class or the
Ellipse
class for any given item in the array? In fact, the source code compiler can‐
not know this at compilation time.
O
Instead,
javac
creates bytecode that uses
virtual
method lookup at runtime. When
the interpreter runs the code, it looks up the appropriate
area()
method to call for
each of the objects in the array. That is, when the interpreter interprets the expres‐
sion
o.area()
, it checks the actual runtime type of the object referred to by the vari‐
able
o
and then finds the
area()
method that is appropriate for that type.
Some other languages (such as
C#
or C++) do not do virtual
lookup by default and instead have a
virtual
keyword that
programmers must explicitly use if they want to allow sub‐
classes to be able to override a method.
The JVM does not simply use the
area()
method that is associated with the static
type of the variable
o
, as that would not allow method overriding to work in the way
detailed earlier. Virtual method lookup is the default for Java instance methods. See
Chapter 4
for more details about compile-time and runtime type and how this
affects virtual method lookup.
Invoking an overridden method
We've seen the important differences between method overriding and field hiding.
Nevertheless, the Java syntax for invoking an overridden method is quite similar to
the syntax for accessing a hidden field: both use the
super
keyword. The following
code illustrates:
class
A
{
int
i
=
1
;
// An instance field hidden by subclass B
int
f
()
{
return
i
;
}
// An instance method overridden by subclass B
}