Step 59: Missing Opportunities for Polymorphism~ Kirk Pepperdine

Birat Rai
2 min readApr 3, 2019

--

This is the 59th Step towards gaining the Programming Enlightenment series. If you didn’t learn the 58th Step, read it.

Polymorphism is the use of a single symbol to represent different types.

Polymorphism is taken from Greek, meaning poly(many) and morph(forms). It is one of the fundamental principal in Object Oriented Programming.

It describes the ability of a particular class of objects to have multiple forms with the help of a single interface for differing underlying forms (data types).

Let’s see the following example;

We have a ShoppingCart that has a number of Item which can be either downloaded or needs to be physically shipped.

public class ShoppingCart {
private ArrayList<Item> cart = new ArrayList<Item>();
public void add(Item item) { cart.add(item); }
public Item takeNext() { return cart.remove(0); }
public boolean isEmpty() { return cart.isEmpty(); }
}

We can define another object that helps in Shipping.

public class Shipping {
public boolean ship(Item item, SurfaceAddress address) { ... }
public boolean ship(Item item, EMailAddress address { ... }
}

In this case, if the client wants to complete the checkout and ship the items, we would have the following code.

while (!cart.isEmpty()) {
shipping.ship(cart.takeNext(), ???);
}

The parameter described here ???, isn’t some fancy elvis operator, rather it’s the shipping method ie by EmailAddress or SurfaceAddress. Since, the ShoppingCart doesn’t have any context, we would require if-then-else condition for checking the type of item before we can ship.

If we had implemented proper Polymorphism, this problem would have been solved without the requiring if-then-else. Let’s define an interface Item which will be implemented by two classes DownloadableItem and SurfaceItem.

public class DownloadableItem implements Item {
public boolean ship(Shipping shipper) {
shipper.ship(this, customer.getEmailAddress());
}
}


public class SurfaceItem implements Item {
public boolean ship(Shipping shipper) {
shipper.ship(this, customer.getSurfaceAddress());
}
}

Here, we have delegated the responsibility of Shipping to each item. Since, now the item knows how it can be shipped, we no longer require if-then-else.

Here, we have used Command and Double Dispatch pattern to achieve polymorphism.

while (!cart.isEmpty()) {
cart.takeNext().ship(shipping);
}

--

--

Birat Rai
Birat Rai

No responses yet