Inheritance in Python allows us to define a class by using the functionality of the parent class. Let's see an example where we will derive a dog class from an animal class.

Suppose we have an `Animal`

class:

```
class Animal:
def eat(self):
print('I can eat')
```

Now, let's derive a `Dog`

class from Animal:

```
class Animal:
def eat(self):
print('I can eat')
class Dog(Animal):
def bark(self):
print('I can bark')
```

From the above code, you can see that we have included the parent class inside the bracket along with the child class.

**Syntax:**

```
# Dog class inherits Animal class
class Dog(Animal):
# code inside dog class
```

During inheritance, the object of the child class (`Dog`

) can
access methods and attributes of both the parent class (`Animal`

)
and the child class.

```
class Animal:
def eat(self):
print('I can eat')
class Dog(Animal):
def bark(self):
print('I can bark')
dog1 = Dog()
dog1.bark()
dog1.eat()
```

**Output**

I can bark I can eat

Here, We have created an object of the `Dog`

class named
`dog1`

. We then used this object to access the method of

- parent class,
`eat()`

- child class,
`bark()`

### Inherit Multiple Classes from a Single Class

Similarly, we can also derive another class, named `Cat`

, from the
`Animal`

class:

```
class Animal:
def eat(self):
print('I can eat')
class Dog(Animal):
def bark(self):
print('I can bark')
class Cat(Animal):
def get_grumpy(self):
print('I am getting grumpy.')
dog1 = Dog()
dog1.bark()
dog1.eat()
cat1 = Cat()
cat1.eat()
```

**Output**

I can bark I can eat I can eat

Now the object of the `Cat`

class (`cat1`

) can also
access the method of the parent class (`Animal`

).

## Example of Python Inheritance

Let's see one more example of Python Inheritance.

This time we will use inheritance to calculate the perimeter of different polygons like triangles and quadrilaterals using inheritance.

Let's first create a base class called `Polygon`

:

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
perimeter = sum(self.sides)
return perimeter
```

All polygons, like triangles and quadrilaterals, will derive the features of
`Polygon`

.

Let's create a `Triangle`

class that will inherit from the
`Polygon`

class:

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
perimeter = sum(self.sides)
return perimeter
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
```

We have redefined the `display_info()`

method to display
information specific to triangles.

Similarly, we can also define a new `Quadrilateral`

class.

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
perimeter = sum(self.sides)
return perimeter
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
class Quadrilateral(Polygon):
def display_info(self):
print('A quadrilateral is a polygon with 4 edges')
```

Now, let's find the perimeter of a triangle. For this, we will create an
object from `Triangle`

and use its
`get_perimeter()`

method.

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
value = 0
for side in self.sides:
value += side
return value
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
class Quadrilateral(Polygon):
def display_info(self):
print('A quadrilateral is a polygon with 4 edges')
t1 = Triangle([5, 6, 7])
perimeter = t1.get_perimeter()
print('Perimeter:', perimeter)
```

**Output**

Perimeter: 18

Here, the `Triangle`

class inherits `Polygon`

, so it is
able to use the `get_perimeter()`

method to find the perimeter of
the triangle.

## Method Overriding

If you have noticed in the above example, we have the
`display_info()`

method in both our base class and the derived
classes.

Let's see what will happen if we call the `display_info()`

method
using the `t1`

object of `Triangle`

.

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
perimeter = sum(self.sides)
return perimeter
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
class Quadrilateral(Polygon):
def display_info(self):
print('A quadrilateral is a polygon with 4 edges')
t1 = Triangle([5, 6, 7])
perimeter = t1.get_perimeter()
print('Perimeter:', perimeter)
t1.display_info()
```

**Output**

Perimeter: 18 A triangle is a polygon with 3 edges

We can see that the `display_info()`

method of the
`Triangle`

class is called, and `display_info()`

of its
parent class is not executed.

This is because when the same method is present in both the child and parent
classes, the method in the child class will override the same method in the
parent class. This concept is called **method overriding**.

If we need, we can call the `display_info()`

method of our parent
`Polygon`

class from inside its child classes:

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
perimeter = sum(self.sides)
return perimeter
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
# call display_info() of parent class
Polygon.display_info(self)
class Quadrilateral(Polygon):
def display_info(self):
print('A quadrilateral is a polygon with 4 edges')
t1 = Triangle([5, 6, 7])
perimeter = t1.get_perimeter()
print('Perimeter:', perimeter)
t1.display_info()
```

**Output**

Parameter: 18 A triangle is a polygon with 3 edges A polygon is a two dimensional shape with straight lines

**Note:** `Polygon`

is the name of the parent class.
Since we are calling the method using a class rather than an object, we also
need to pass the `self`

object manually.

This code is a bit more unorthodox than what we have been using. There is a
more elegant way to achieve the same task by using the
`super()`

function.

## The super() function

The `super()`

function returns a temporary object of the parent
class and allows us to call the methods of the parent class from within the
child class.

```
class Polygon:
def __init__(self, sides):
self.sides = sides
def display_info(self):
print('A polygon is a two dimensional shape with straight lines')
def get_perimeter(self):
value = 0
for side in self.sides:
value += side
return value
class Triangle(Polygon):
def display_info(self):
print('A triangle is a polygon with 3 edges')
# Polygon.display_info(self)
super().display_info()
class Quadrilateral(Polygon):
def display_info(self):
print('A quadrilateral is a polygon with 4 edges')
t1 = Triangle([5, 6, 7])
perimeter = t1.get_perimeter()
print('Perimeter:', perimeter)
t1.display_info()
```

**Output**

Parameter: 18 A triangle is a polygon with 3 edges A polygon is a two dimensional shape with straight lines

In this case, `super()`

is an object of `Polygon`

. We
are using it to call `display_info()`

of the
`Polygon`

class.