Subtype Polymorphism

Polymorphism means "many forms". In programming it means "many types" and refers to the possibility that a single object may have multiple types.

The types of an object include the class it instantiates as well as all classes and interfaces it inherits from.

Having many types means that an object can appear in many contexts.

The Subsumption Principle: If class A extends class B or implements interface C, then instances of A can masquerade as instances of B and C.

Example: Ultra Dome

Ultra Dome is a computer game in which gladiators fight each other to the death.

Here's the basic design:

 

Implementation

·       Gladiator.java

·       Weapon.java

Demo

Here's a simple battle:

public class UltraDome {

  public static void main(String[] args) {
     Gladiator xena = new Gladiator("Xena");
     Gladiator star = new Gladiator("Star");
    
     xena.setWeapon(new Wand());
     star.setWeapon(new Sword());
    
     xena.fight(star);
     star.fight(xena);
    
     xena.setWeapon(new Whip());
     xena.fight(star);

  }

}

And here's the output produced:

Xena is fighting Star
Mesmerizing Star
Star health = 97
Star is fighting Xena
Slashing Xena
Xena health = 95
Xena is fighting Star
Snapping Star
Star health = 93

Things to Notice

1. A gladiator's setWeapon method sets its weapon field:

public void setWeapon(Weapon weapon) { this.weapon = weapon; }

But in the demo we see different types of weapons being used:

xena.setWeapon(new Wand());
star.setWeapon(new Sword());

This is allowed because Wand, Sword, and Whip extend Weapon and so can be used in contexts where weapons are expected.

2. Normally all instances of the same class have the same behavior, but Xena and Star are gladiators, yet when Xena's fight method is called we see a different behavior from when Star's fight method is called.

3. Normally, an object can't change its behavior, but Xena's fight method at first mesmerizes Star, then later snaps her.

Data-Driven Programming (versus Control-Driven Programming)

The Principle: Data, not programmers, determine the flow of control.

·       For example: what code will be executed when Xena's fight method is called?

·       Control-Driven Evil: dispatchers methods containing multi-way conditionals (switch and else-ifs) that need to be updated each time a new class is added to the program.

·       How does polymorphism enable Data-Driven?

The Open-Closed Principle

The Principle: Programs should be open to extension, but closed to modification.

·       Get haircuts from barbers, not brain surgeons.

·       How does inheritance enable Open-Closed?

·       How does Data-Driven Programming enable Open-Closed?

Polymorphic Collections

A polymorphic or heterogeneous collection contain members of different types:

Set<Weapon> armory = new HashSet<Weapon>();
armory.add(new Sword());
armory.add(new Sword());
armory.add(new Wand());
armory.add(new Whip());

The Strategy Design Pattern

We can regard weapons as attack strategies.

Lab

The SOP language has three types of expressions: numbers, sums, and products. A sum is the token "sum" followed by a list of expressions. A product is the token "mul" followed by a list of expressions.

·       More formally:

exp ::= number | (add|mul)~ "(" ~ exp* ~ ")"

·       For example:

add(mul(2 add(1 2 2) 7) add(4 5)) // = 720

·       Design and implement the SOP expression hierarchy.