Chapter 12: Polymorphism

If you're expecting this chapter to be about a band of teenagers with "attitude" that transform into superhuman heroes, you're bound to be gravely disappointed, but don't worry. Polymorphism is just as cool as any 90's TV show.


What you will learn

  • What is Polymorphism?
  • Creating a base Class with requirements
  • Creating a Subclass
  • Implementing base Class requirements in a Subclass

Key Terms

  • Polymorphism: being able to assign a different usage to something (like a class) in different contexts - specifically, to allow something like a variable, a function, or an object to have more than one form.

In this chapter, you will end your voyage into the basics of Object-Oriented Programming by reading about Polymorphism. Other than being a really cool word, polymorphism is a very important concept to understand when becoming a programmer.

It is common in a developer job interview to be asked, "Can you please define 'polymorphism'?" Instead of looking like a deer in the headlights, we are going to break down what polymorphism is, what it means, and how it actually plays out in code.

What is Polymorphism?

A long-winded programming definition for polymorphism is: "Polymorphism allows the expression of some sort of contract, with potentially many types implementing that contract in different ways, each according to their own purpose."

That may be a bit of a textbook definition, but the basic concept here is that our code can occur in many different forms and its functions can be implemented in different ways.

This may still be confusing and that is okay. Let's build a code example as it is much easier to understand polymorphism this way.

Creating a new project

First, open Xcode if you haven't already and click Create New Playground. Give it a name like Polymorphism and click Next. Choose somewhere to save this .playground file and click Create to save it. You should see a screen like the one in Figure 1.12.1.

Figure 1.12.1 Screen Shot 2016-10-10 at 5.01.11 AM.png

Delete all the boilerplate code on the left side but leave import UIKit as it is necessary.

Creating a base Class with default functions

To begin, we will create a class called Shape with an area property and a function to calculate the area of our shape. Add the following to your Playground:

class Shape {
    var area: Double?

    func calculateArea(valueOne: Double, valueTwo: Double) {

    }
}

Our base class Shape contains everything we need – a variable to store the area and a function to calculate an area with two input values.

Let's create a child class to inherit from our Shape class. What we need to do to demonstrate polymorphism is to obey the "contract" set in Shape, which is to have a calculateArea function.

Creating a Triangle Subclass

Add the following class and override the function calculateArea(valueA:valueB:) at the bottom of your Playground:

class Shape {
    var area: Double?

    func calculateArea(valueA: Double, valueB: Double) {

    }
}

class Triangle: Shape {
    override func calculateArea(valueA: Double, valueB: Double) {
        area = (valueA * valueB) / 2
    }
}

We now have created a subclass called Triangle and have overridden the function to calculate the area. We're calling the same function, but the code inside is relevant to a triangle only.

This is polymorphism in action. The class Shape has a contract that all subclasses must follow which is to use the function calculateArea(valueA:valueB:). We used it and wrote custom code inside to calculate a triangle's area.

Let's now create a Rectangle subclass and override calculateArea(valueA:valueB:).

Creating a Rectangle Subclass

Add the following code beneath the Triangle class:

...

class Rectangle: Shape {
    override func calculateArea(valueA: Double, valueB: Double) {
        area = valueA * valueB
    }
}

Now we have two separate classes implementing the same exact function, but the logic inside is different – this is polymorphism. One object (Shape) taking different forms (Triangle & Rectangle). We are obeying the contract set by Shape by implementing calculateArea(valueA:valueB:) but in different ways.

Wrapping up

If you're in a job interview and are asked to define polymorphism, you can instead give them an example to explain that you understand the concept.

For instance:

Imagine that you have a Shape class and you need to calculate the area of a shape, but you don't know which shape will be passed in at runtime.

So, we create a calculateArea function and we also create two more classes for Triangle and Rectangle that inherit from Shape and at runtime they can each perform their own area calculation independent of each other and assign it into the area value.

It doesn't need to know beforehand what type of shape to pick because we have a different implementation set for each shape.

Polymorphism is a simple concept with a really technical definition but I hope you can see how easy it is to implement in code.

In summary, we created a base class called Shape which had a variable called area and a function called calculateArea(valueA:valueB:).

Then, we created two subclasses called Triangle and Rectangle. They each inherited from Shape. We obeyed the requirements from Shape and implemented and overrode the function calculateArea(valueA:valueB:).

Inside each individual subclass, we added custom logic to calculate the areas for those particular shapes.

Polymorphism is what makes this possible.

Exercise

Create an subclass of Shape for a parallelogram. Override the area function so that it can calculate it's area. The formula for the area of a parallelogram is A = b x h. You're welcome. 😉