Polymorphism means "many forms" (poly = many, morphos = form). Pure polymorphism occurs when a single function can be applied to arguments of a variety of types. There is one function and a number of interpretations. The other extreme occurs when we have a number of different functions all denoted by the same name - a situation known as overloading. Between these two methods are over-riding and deferred methods.

A polymorphic variable is one that can hold values of different types. An array can be declared as maintaining values of the parent class but in fact maintains values from each of the different subclasses of the parent class.

In overloading the method name is polymorphic. There is a single abstract function that takes various types of arguments. The actual code executed depends on the arguments given.

Overriding occurs when a subclass inherits a method from a super class and either hides access to this method or refines it.

A method that is declared as abstract can be thought of as defining a method that is deferred; it is specified in the parent class but must be implemented in a descendent class. Interfaces can also be viewed as a method for defining deferred classes. An interface is a collection of operations that are used to specify a service of a class or a component.


Interfaces formalize polymorphism. Interfaces allow us to define polymorphism in a declarative way, unrelated to implementation. Two elements are polymorphic with respect to a set of behaviors if they realize the same interfaces. You always heard that polymorphism was this big benefit of object orientation, but without interfaces there was no way to enforce it, verify it, or even express it, except in informal ways, or language-specific ways. Formalization of interfaces strips away the mystery, and gives us a good way to describe, in precise terms, what polymorphism was trying to do all along. Interfaces are testable, verifiable, and precise.

Interfaces are the key to the "plug-and-play" ability of an architecture. Classes that realize the same interface may be substituted for one another in the system, thereby supporting the changing of implementations without affecting clients.

interface Stack
  public void push ( char item );  // inserts an item at the top 
  public char pop ();              // removes an item from the top
  public char peek ();             // returns an item from the top 
				   // without removing
  public boolean isEmpty ();       // determines if the Stack is empty
  public boolean isFull ();        // determines if the Stack is full
  public String toString ();       // returns a String representation of
				   // the Stack

class StackArray implements Stack
  private char stackArray[];	// array that implements the Stack
  private int top;		// index of the top element in the Stack

  // Constructor
  public StackArray ( int n )
    stackArray = new char [ n ];
    top = -1;

  // Implementation of the methods in the interface
  public void push ( char item )
  {  stackArray [ ++top ] = item;  }

  public char pop ()
  {  return stackArray [ top-- ];  }

  public char peek ()
  {  return stackArray [ top ];  }

  public boolean isEmpty ()
  {  return ( top < 0 );  }

  public boolean isFull ()
  {  return ( top == stackArray.length - 1 );  }

  public String toString ()
  { StringBuffer aBuffer = new StringBuffer();
    for ( int i = top; i >= 0; i-- )
      aBuffer.append ( stackArray [ i ] + "  " );
    return aBuffer.toString();

public class TestStack
  public static void main ( String args [] )
    Stack theStack = new StackArray ( 10 );
    char ch = ' ';

    if ( !theStack.isFull() )
      theStack.push ( 'a' );

    if ( !theStack.isFull() )
      theStack.push ( 'b' );

    if ( !theStack.isFull() )
      theStack.push ( 'c' );

    if ( !theStack.isEmpty() )
      ch = theStack.pop ();
    System.out.println ( "The item on top of the stack is " + ch );

    if ( !theStack.isEmpty() )
      ch = theStack.peek ();
    System.out.println ( "The item on top of the stack is " + ch );

    System.out.println ( theStack.toString() );