Intro to Python: Day 13 - OOP - What is polymorphism? 🧐
Tags: python, webdev, programming, beginners
Published: 2023-08-20 13:33:47

*Hi there 👋 I'm a New York City based web developer documenting my journey with React, React Native, and Python for all to see. Please follow my dev.to profile or [my twitter](https://twitter.com/stonestwebdev) for updates and feel free to reach out if you have questions. Thanks for your support!*

Today we follow up on a series of posts about Object Oriented Programming in Python. You can check out yesterday's article [here](https://dev.to/jwhubert91/intro-to-python-day-12-oop-calling-a-parent-method-36g9).

We've been talking about inheritance in OOP recently, and yesterday's blog post discussed how a child class can inherit variables and methods from a parent class. This is useful if you want the same behavior in a child that a parent has.

But what if you want different behavior in the child class than a parent has, but want to inherit everything else? This is where **polymorphism** comes in.

Let's say you have an `Organism` class. Just like in biology, all animals and plants are types of organisms. So we might have a `eat()` method on the organism class (all organisms like to eat!).

On the parent `Organism` class the eat method look like this:

```python
class Organism:
    def __init__(self, name):
        self.name = name

    def eat(calories):
        print(f"{self.name} ate a meal of {calories} calories")
```

In the above class, we have a constructor function where we can pass in a name and an instance variable `name` that we set it to. So now our organism has a name! In the `eat` method, we pass in a number of calories and our method prints out how many calories it ate.

Let's say our organism is a plant. Plants don't eat food like you and I do, instead they get their food from the sun and convert it to energy. So eating calories doesn't make sense for a `Plant` class, even if it inherits from the `Organism` class. So instead we want to inherit everything else from `Organism` but the `eat()` method should accept a `hours_of_sunlight` argument instead of `calories`.

Our `Plant` class might look like this:

```python
class Plant(Organism):
    def __init__(self, name, type):
        super().__init__(name)
        self.type = type

    def eat(hours_of_sunlight):
        print(f"The {self.type} plant converted {hours_of_sunlight} hours of sunlight into energy!")
```

In the above example, the `Plant` class calls the parent's constructor function using `super().__init__()` in its constructor, thereby inheriting the `name` variable and setting it, which is awesome!. We also set a new instance variable called `type` where we can pass in things like "palm tree" or "sunflower" or "green ivy".

After creating an instance of `Plant` the `eat` method would be available on it the instance because it would come from the parent. But as we said we want the `Plant` class' `eat` method to be different! So to do this we simply create a *new* method on the `Plant` class with the same name- `eat()`.

Now, when an instance of `Plant` is created and its `eat` method is called, instead of printing a line about how many calories it consumed, we describe how many hours of sunlight it converted into energy!

This ability to selectively inherit data and methods from the parent but also **take on a new form** if need be, by overwriting methods and variables inherited from the parent, is called **polymorphism**.

**If you like projects like this and want to stay up to date with more, check out my Twitter [@stonestwebdev](https://twitter.com/stonestwebdev), I follow back! See you tomorrow for another project.**