# Polymorphism

Polymorphism is one of the most important features of inheritance, but it’s fairly challenging to describe without showing some examples. To start, let’s go back to using examples related to robotics programming.

You’ll see later that it can be helpful to group robot code into `Command` classes, where `Command` is a base class that has multiple derived classes representing different types of commands. For example, there may be a `MoveForward` command, or a `Rotate` command, both of which inherit from the `Command` class. Here’s what that could look like:

```#include <iostream>

class Command {
public:
virtual void run() = 0;
};

class MoveForward : public Command {
private:
float distance_ft;

public:
MoveForward(float distance_ft) {
this->distance_ft = distance_ft;
}
void run() override {
std::cout << "Moving forward " << distance_ft << " feet...\n";
}
};

class Rotate : public Command {
private:
float angle_deg;

public:
Rotate(float angle_deg) {
this->angle_deg = angle_deg;
}
void run() override {
std::cout << "Rotating " << angle_deg << " degrees...\n";
}
};

int main() {
MoveForward move(2.5);
Rotate rotate(90);

Command *moveCommand = &move;
Command *rotateCommand = &rotate;

moveCommand->run();
rotateCommand->run();

return 0;
}
```

Program output:

```Moving forward 2.5 feet...
Rotating 90 degrees...
```

Now, this code uses polymorphism, so I’ll start by showing what polymorphism is and how it works. After that, I’ll show you when it’s useful.

Let’s start in the `main` function:

• We first create instances of the `MoveForward` and `Rotate` classes, just like we’ve done previously.
• The `move` object is constructed with a `distance_ft` value of 2.5, and the `rotate` object is constructed with an `angle_deg` value of 90.
• The next two lines are where polymorphism comes into play.
• Polymorphism allows you to represent the data type of an object as a pointer to the object’s base class. This means we can create the pointer “`moveCommand`” with an underlying data type of “`Command`“, even though the `move` object actually has the data type “`MoveForward`“. This works because `MoveForward` is a `Command`. The same applies to the `rotate` object.
• Note that polymorphism only works when using pointers (or references).
• Lastly, we use the `run` function on both of the `Command` pointers.
• Here, you may see that the `run` function inside the `Command` class doesn’t really do much. When using polymorphism, the function used depends on the derived class that the pointer represents. Therefore, `moveCommand->run();` calls the `run` function from the `MoveForward` class, not from the `Command` class.

Now let’s look at the code in each of the classes:

• The `Command` class contains a function called “`run`” that looks quite a bit different from what we’ve seen before.
• The word “`virtual`” means that the function can be “overriden” by functions in derived classes.
• You can see that both the `MoveForward` and the `Rotate` classes have their own `run` functions with the word `override` after their parentheses. This means that these two functions “override” (replace) the `run` function in their base class (the `Command` class).
• The “` = 0;`” following the `Command` class’s `run` function turns it into a “pure virtual function“. This means that the function has no “implementation” (functionality), so it can never be called. This is fine, though, because the function is overriden in its two derived classes.
• This function is made a pure virtual function because it doesn’t make sense to “run” just a “`Command`“. Running the `MoveForward` or `Rotate` commands, however, makes sense because those commands perform a specific task.
• Any class that has at least one pure virtual function is called an “abstract class.” Abstract class instances are not allowed (so I cannot create a `Command` object). However, as you saw in the `main` function, abstract class pointers are allowed, as long as they point to an object of a non-abstract derived class (such as `MoveForward` or `Rotate`).
##### So what?

A normal initial reaction to polymorphism is thinking that it’s overly complex and doesn’t provide any benefits (at least that’s what I first thought).

Generally, polymorphism is useful because it allows us to store objects of different (but related) data types all in one place (e.g. an array or vector). By using polymorphism with robot commands, we can store a sequence of different commands all inside a single vector. This wouldn’t work without polymorphism because vectors can only store values of a single data type. With polymorphism, that single data type is a base class pointer:

```#include <iostream>
#include <vector>

class Command {
public:
virtual void run() = 0;
};

class MoveForward : public Command {
private:
float distance_ft;

public:
MoveForward(float distance_ft) {
this->distance_ft = distance_ft;
}
void run() override {
std::cout << "Moving forward " << distance_ft << " feet...\n";
}
};

class Rotate : public Command {
private:
float angle_deg;

public:
Rotate(float angle_deg) {
this->angle_deg = angle_deg;
}
void run() override {
std::cout << "Rotating " << angle_deg << " degrees...\n";
}
};

int main() {
MoveForward move(2.5);
Rotate rotate(90);

std::vector<Command*> commandSequence = {&move, &rotate};
for (int i = 0; i < commandSequence.size(); i++) {
commandSequence[i]->run();
}

return 0;
}
```

Program output:

```Moving forward 2.5 feet...
Rotating 90 degrees...
```

When structuring our code like this, we can also easily add new commands to the `commandSequence` vector later on (if a button on a controller is pressed, for example). Of course, this only works if the command added inherits from the `Command` class.

### A Deeper Look into “`virtual`“

In case you don’t fully understand how the keyword “`virtual`” affects functions, let’s look at some other cases:

##### Non-Virtual Function in Base Class

By changing the `Command` class to this…

```class Command {
public:
void run() {
std::cout << "Default command running...\n";
}
};
```

…the program won’t compile because the other two `run` functions use the “`override`” keyword. When a function in the base class is not virtual, the function cannot be overriden by derived classes.

Let’s remove the word “`override`” from the other classes and see what happens:

```#include <iostream>
#include <vector>

class Command {
public:
void run() {
std::cout << "Default command running...\n";
}
};

class MoveForward : public Command {
private:
float distance_ft;

public:
MoveForward(float distance_ft) {
this->distance_ft = distance_ft;
}
void run() {
std::cout << "Moving forward " << distance_ft << " feet...\n";
}
};

class Rotate : public Command {
private:
float angle_deg;

public:
Rotate(float angle_deg) {
this->angle_deg = angle_deg;
}
void run() {
std::cout << "Rotating " << angle_deg << " degrees...\n";
}
};

int main() {
MoveForward move(2.5);
Rotate rotate(90);

std::vector<Command*> commandSequence = {&move, &rotate};
for (int i = 0; i < commandSequence.size(); i++) {
commandSequence[i]->run();
}

return 0;
}
```

Program output:

```Default command running...
Default command running...
```

Now the `Command` class’s `run` function is used because it is not overriden by its derived classes.

##### Virtual (but not Pure) Function in Base Class

Let’s now add the word “`virtual`” back to the `run` function in the `Command` class and add the word “`override`” back to the other two `run` functions. However, rather than making the `Command` class’s `run` function “pure virtual” (set equal to 0), let’s keep its implementation the same:

```class Command {
public:
virtual void run() {
std::cout << "Default command running...\n";
}
};
```

Even though `run` is a virtual function, the `Command` class is not an abstract class in this case (because it doesn’t have at least one pure virtual function). This means that a `Command` object can be created:

```#include <iostream>
#include <vector>

class Command {
public:
virtual void run() {
std::cout << "Default command running...\n";
}
};

class MoveForward : public Command {
private:
float distance_ft;

public:
MoveForward(float distance_ft) {
this->distance_ft = distance_ft;
}
void run() override {
std::cout << "Moving forward " << distance_ft << " feet...\n";
}
};

class Rotate : public Command {
private:
float angle_deg;

public:
Rotate(float angle_deg) {
this->angle_deg = angle_deg;
}
void run() override {
std::cout << "Rotating " << angle_deg << " degrees...\n";
}
};

int main() {
MoveForward move(2.5);
Rotate rotate(90);
Command genericCommand;

std::vector<Command*> commandSequence = {&move, &rotate, &genericCommand};
for (int i = 0; i < commandSequence.size(); i++) {
commandSequence[i]->run();
}

return 0;
}
```

Program output:

```Moving forward 2.5 feet...
Rotating 90 degrees...
Default command running...
```

In this program, objects of the `Command` class can be created that have their own `run` function. Since that `run` function is virtual, however, it can be overriden by the other two classes.

### Challenge Problem

Write a program that follows the specifications below:

• Create a `Shape` class that is abstract
• The class should contain a pure virtual function called “`draw`
• Create an `EquilateralTriangle` class that inherits from `Shape` (using public inheritance).
• The class should include a constructor and an override of the `draw` function.
• The constructor should include one parameter for the triangle’s side length.
• The `draw` function should print a triangle to the screen that corresponds to the triangle’s side length.
• Create a `Rectangle` class that inherits from `Shape` (using public inheritance).
• The class should include a constructor and an override of the `draw` function.
• The constructor should include two parameters for the rectangle’s side lengths.
• The `draw` function should print a rectangle to the screen that corresponds to the rectangle’s width and height.
• Create a `Square` class that inherits from `Rectangle` (using public inheritance).
• The class should include a constructor with one parameter for the square’s side length.
• The constructor should also call `Rectangle`‘s constructor.
• The `main` function should include a vector containing multiple shapes.
• Loop through the vector and call the `draw` function for each shape.
• Drawing the shapes could be done with any character you’d like (I chose the asterisk).

Sample output:

```    *
* *
* * *
* * * *
* * * * *

* * * * * *
* * * * * *
* * * * * *
* * * * * *

* * * *
* * * *
* * * *
* * * *
```

This output was produced using a triangle with a side length of 5, a 4×6 rectangle, and a square with a side length of 4.

If you get stuck, check out my solution here.