Overriding vs. overloading

Bruce Eckel’s Thinking in Java Contents | Prev | Next

Let’s
take a different look at the first example in this chapter. In the following
program, the interface of the method
play( )
is changed in the process of overriding it, which means that you haven’t
overridden
the method, but instead
overloaded
it.
The compiler allows you to overload methods so it gives no complaint. But the
behavior is probably not what you want. Here’s the example:

//: WindError.java 
// Accidentally changing the interface
 
class NoteX {
  public static final int
    MIDDLE_C = 0, C_SHARP = 1, C_FLAT = 2;
}
 
class InstrumentX {
  public void play(int NoteX) {
    System.out.println("InstrumentX.play()");
  }
}
 
class WindX extends InstrumentX {
  // OOPS! Changes the method interface:
  public void play(NoteX n) {
    System.out.println("WindX.play(NoteX n)");
  }
}
 
public class WindError {
  public static void tune(InstrumentX i) {
    // ...
    i.play(NoteX.MIDDLE_C);
  }
  public static void main(String[] args) {
    WindX flute = new WindX();
    tune(flute); // Not the desired behavior!
  }
} ///:~ 

There’s
another confusing aspect thrown in here. In
InstrumentX,
the
play( )
method takes an
int
that has the identifier
NoteX.
That is, even though
NoteX
is a class name, it can also be used as an identifier without complaint. But in
WindX,
play( )
takes a
NoteX
handle that has an identifier
n.
(Although you could even say
play(NoteX
NoteX)

without an error.) Thus it appears that the programmer intended to override
play( )
but mistyped the method a bit. The compiler, however, assumed that an overload
and not an override was intended. Note that if you follow the standard Java
naming convention, the argument identifier would be
noteX,
which would distinguish it from the class name.

In
tune,
the
InstrumentX
i
is sent the
play( )
message, with one of
NoteX’s
members (
MIDDLE_C)
as an argument. Since
NoteX
contains
int
definitions, this means that the
int
version of the now-overloaded
play( )
method is called, and since that has
not
been overridden the base-class version is used.

The
output is:

InstrumentX.play()

This
certainly doesn’t appear to be a polymorphic method call. Once you
understand what’s happening, you can fix the problem fairly easily, but
imagine how difficult it might be to find the bug if it’s buried in a
program of significant size.

More by Author

Must Read