img
r = a; // r refers to an A object
r.callme(); // calls A's version of callme
r = b; // r refers to a B object
r.callme(); // calls B's version of callme
r = c; // r refers to a C object
r.callme(); // calls C's version of callme
}
}
The output from the program is shown here:
Inside A's callme method
Inside B's callme method
Inside C's callme method
This program creates one superclass called A and two subclasses of it, called B and C.
Subclasses B and C override callme( ) declared in A. Inside the main( ) method, objects of
type A, B, and C are declared. Also, a reference of type A, called r, is declared. The program
then in turn assigns a reference to each type of object to r and uses that reference to invoke
callme( ). As the output shows, the version of callme( ) executed is determined by the type
of object being referred to at the time of the call. Had it been determined by the type of the
reference variable, r, you would see three calls to A's callme( ) method.
NOTE  Readers familiar with C++ or C# will recognize that overridden methods in Java are similar
OTE
to virtual functions in those languages.
Why Overridden Methods?
As stated earlier, overridden methods allow Java to support run-time polymorphism.
Polymorphism is essential to object-oriented programming for one reason: it allows a
general class to specify methods that will be common to all of its derivatives, while allowing
subclasses to define the specific implementation of some or all of those methods. Overridden
methods are another way that Java implements the "one interface, multiple methods" aspect
of polymorphism.
Part of the key to successfully applying polymorphism is understanding that the
superclasses and subclasses form a hierarchy which moves from lesser to greater specialization.
Used correctly, the superclass provides all elements that a subclass can use directly. It also
defines those methods that the derived class must implement on its own. This allows the
subclass the flexibility to define its own methods, yet still enforces a consistent interface.
Thus, by combining inheritance with overridden methods, a superclass can define the general
form of the methods that will be used by all of its subclasses.
Dynamic, run-time polymorphism is one of the most powerful mechanisms that object-
oriented design brings to bear on code reuse and robustness. The ability of existing code
libraries to call methods on instances of new classes without recompiling while maintaining
a clean abstract interface is a profoundly powerful tool.
Search WWH :
Custom Search
Previous Page
Java SE 6 Topic Index
Next Page
Java SE 6 Bookmarks
Home