Polymorphism

Recall that A is a subclass of B, A <: B, if A = B, A extends B, or A extends some other subclass of B.

Recall that if A <: B, then A inherits all of the methods and fields of B.

Polymorphism means that an instance of A can masquerade as an instance of B. For example, a variable of class B can hold a reference to an instance of class A:

B b = new A();

What happens when a method is invoked?

b.meth(); // calls A.meth

If class A has overridden meth, then the overridden method is invoked. This is called dynamic dispatch.

Example

Assume an object representing an office contains a reference to the employee occupant:

Main

Here's an implementation:

class Employee {
   public void getToWork() {
      System.out.println("look busy");
   }
}

class Programmer extends Employee {
   public void getToWork() {
      System.out.println("fix bugs");
   }
}

class Manager extends Employee {
   public void getToWork() {
      System.out.println("fire somebody");
   }
}

class Office {
   private Employee occupant;
   public void getOccupantTowork() {
      occupant.getToWork();
   }
   public Employee getOccupant() { return occupant; }
   public void setOccupant(Employee e) {
      occupant = e;
   }
}

Notice that Manager and Programmer override the getToWork method inherited from Employee.

Here's a test harness:

class TestOffice {
   public static void main(String[] args) {
      Office[] office = new Office[3];
      for(int i = 0; i < 3; i++) {
         office[i] = new Office();
      }
      office[0].setOccupant(new Employee());
      office[1].setOccupant(new Manager());
      office[2].setOccupant(new Programmer());
      for(int i = 0; i < 3; i++) {
         office[i].getOccupantTowork();
      }
   }
}

Here's the output it produces:

look busy
fire somebody
fix bugs

First notice that while setOccupant method expects an Employee object as an input, it is happy to accept programmers and managers.

Second, each time office[i].getOccupantToWork() is executed, a different method is invoked. This is an example of dynamic dispatch.

Example

For example, the draw method defined in the Window class is automatically inherited by all of its subclasses. However, these subclasses override or redefine the inherited method:

ClassDiagram1

Even though the Desktop class has no knowledge of the Window subclasses, these overrides will automatically be called when the drawWindows method calls w.draw for w some instance of one of these subclasses.