In this first chapter from the book The Art of Java by Herbert Schildt and James Holmes, the authors highlight certain features of the Java programming language that separate it from other languages. The chapter also covers: memory management, Java's built-in support for multithreading, Java's approach to exceptions as compared to C++, Java's support of polymorphism, and how bytecode enables Java's "Write Once, Run Anywhere" ability and provides security. (ISBN 0-07-222971-3, McGraw-Hill/Osborne, 2003).
Polymorphism is the attribute of object-oriented programming that allows one interface to be used by multiple methods. Java supports polymorphism with a variety of features, but two stand out. The first is the fact that every method (other than one marked final) can be overridden by a subclass. The second is the interface keyword. Let’s examine each a bit closer.
Because methods in a superclass can be overridden by those in a derived class, it’s trivially easy to create class hierarchies in which subclasses are specializations of the superclass. Recall that a superclass reference can be used to refer to any subclass of that superclass. Furthermore, a call to a method on a subclass object, through a superclass reference, automatically executes the overridden version of that method. Thus, a superclass can define the form of an object and provide a default implementation. This default implementation can then be customized by a subclass to better meet the needs of a specific situation. Thus, the same interface, in this case the one defined by the superclass, can be the basis for multiple implementations.
Of course, Java takes the concept of “one interface, multiple methods” a step further. It defines the interface keyword, which allows you to fully separate a class’ methods from their implementations. Although an interface is abstract, you can still declare a reference of an interface type. This reference can then be used to refer to any object that implements the interface. This is a very powerful concept because it streamlines and facilitates the use of polymorphism. As long as a class implements an interface, an object of that class can be used by any code that requires the functionality provided by the interface. For example, assuming an interface called MyIF, consider the following method: