# Object-Oriented Programming Mastery: (Part 3)

[Object](https://www.toppr.com/guides/python-guide/tutorials/python-object-and-class/inheritance/python-inheritance-with-examples/)\-[oriented](https://towardsdatascience.com/parents-and-children-in-python-998540210987) [programming](https://www.coursera.org/learn/python-classes-inheritance) ([OOP](https://python-course.eu/oop/inheritance.php)) is a paradigm that has revolutionized software development by enabling modular, organized, and reusable code. Two fundamental concepts are [Inheritance](https://www.geeksforgeeks.org/inheritance-in-python/) and [Polymorphism](https://www.edureka.co/blog/polymorphism-in-python/). This blog explores these concepts in-depth, providing practical examples and real-world scenarios.

We'll use real-world examples and scenarios to show how [inheritance](https://www.programiz.com/python-programming/inheritance) and [polymorphism](https://www.javatpoint.com/polymorphism-in-python) work together to make our code more modular, manageable, and adaptive. So come along with us as we uncover the mysteries of [inheritance](https://www.programiz.com/python-programming/inheritance) and polymorphism in the realm of [object](https://www.codecademy.com/resources/docs/python/inheritance)\-[oriented](https://www.learnbyexample.org/python-inheritance/) [programming](https://www.digitalocean.com/community/tutorials/understanding-class-inheritance-in-python-3).

## Inheritance

*"*[*Inheritance*](https://pynative.com/python-inheritance/) *is a fundamental concept in* [*object*](https://www.scaler.com/topics/python/inheritance-in-python/)*\-*[*oriented*](https://realpython.com/inheritance-composition-python/) *programming (OOP) that allows you to create a new class (subclass or derived class) based on an existing class (superclass or base class). It forms a hierarchy of classes where subclasses* [*inherit*](https://docs.python.org/3/tutorial/classes.html) *attributes and behaviors from their* [*superclass*](https://www.cdslab.org/python/notes/object-oriented-programming/inheritance/inheritance.html)*"*

### Key concepts and terms related to [inheritance](https://www.edureka.co/blog/inheritance-in-python/)

* **Superclass/Base** [**Class**](https://www.cdslab.org/python/notes/object-oriented-programming/inheritance/inheritance.html)
    
* **Subclass/Derived Class**
    
* [**Inheritance**](https://www.knowledgehut.com/tutorials/python-tutorial/python-inheritance) **Relationship**
    
* **Code Reusability**
    
* **Method Overriding**
    
* **Access to Superclass Members**
    
* **"is-a" Relationship**
    
* **Constructor** [**Inheritance**](https://www.pythontutorial.net/python-oop/python-inheritance/)
    
* **Multiple** [**Inheritance**](https://builtin.com/software-engineering-perspectives/python-inheritance)
    
* **Abstract** [**Classes**](https://www.alphacodingskills.com/python/python-inheritance.php)
    
* **Final** [**Classes**](https://www.shiksha.com/online-courses/articles/inheritance-in-python/)**/**[**Methods**](https://prepinsta.com/python/inheritance/)
    

### **Superclass/Base Class**

The [superclass](https://www.tutorialspoint.com/object_oriented_python/object_oriented_python_inheritance_and_ploymorphism.htm) or base [class](https://www.techbeamers.com/python-inheritance/) is the existing [class](https://wiingy.com/learn/python/inheritance-in-python/) from which a new [class](https://geekpython.in/class-inheritance-in-python) is derived. It provides characteristics and methods that subclasses can inherit.

### **Subclass/Derived Class**

The new [class](https://www.pythonlikeyoumeanit.com/Module4_OOP/Inheritance.html) formed from a [superclass](https://python.land/objects-and-classes/python-inheritance) is known as a [subclass](https://data-flair.training/blogs/python-inheritance/) or derived [class](https://pythongeeks.org/inheritance-in-python/). It inherits the [superclass](https://www.gcreddy.com/2021/12/inheritance-in-python.html)'s characteristics and methods and can additionally have its extra attributes and methods.

### **Inheritance Relationship**

It is the established connection between the [superclass](https://www.upgrad.com/blog/types-of-inheritance-in-python/) and its [subclasses](https://www.koderhq.com/tutorial/python/oop-inheritance/). Subclasses [inherit](https://www.analyticsvidhya.com/blog/2020/10/inheritance-object-oriented-programming/) the superclass's traits (attributes and methods).

### **Code Reusability**

One of the key advantages of [inheritance](https://www.datacamp.com/tutorial/super-multiple-inheritance-diamond-problem) is the ability to reuse code. In a base [class](https://www.prepbytes.com/blog/python/types-of-inheritance-in-python/), you may declare common characteristics and methods that are immediately available to all [subclasses](https://pythonbasics.org/inheritance/). This removes redundancy while also encouraging a more ordered and efficient codebase.

```python
# Base class: Animal
class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self, food):
        return f"{self.name} is eating {food}."

# Subclass: Dog (inherits from Animal)
class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

    def bark(self):
        return "Woof!"

# Subclass: Cat (inherits from Animal)
class Cat(Animal):
    def __init__(self, name, color):
        super().__init__(name)
        self.color = color

    def meow(self):
        return "Meow!"

# Create instances of Dog and Cat
my_dog = Dog("Buddy", "Golden Retriever")
my_cat = Cat("Whiskers", "Gray")

# Use methods from the base class and subclasses
print(my_dog.eat("dog food"))    # Outputs: "Buddy is eating dog food."
print(my_cat.eat("cat food"))    # Outputs: "Whiskers is eating cat food."
print(my_dog.bark())             # Outputs: "Woof!"
print(my_cat.meow())             # Outputs: "Meow!"
```

### **Method Overriding**

[Subclasses](https://datatrained.com/post/python-inheritance/) can implement methods inherited from the [superclass](https://pythonlobby.com/inheritance-and-types-of-inheritance-in-python-programming/) in their way. Method overriding is a technique that allows [subclasses](https://blog.finxter.com/inheritance-in-python-harry-potter-example/) to alter the behavior of inherited methods.

### **Access to Superclass Members**

[Subclasses](https://pythonprogramminglanguage.com/inheritance/) have access to all of their [superclass](https://dyclassroom.com/python/python-inheritance)'s non-private (public and protected) properties and methods. These members can be used, overridden, or extended as needed.

```python
# Base class: Animal
class Animal:
    def __init__(self, name):
        self.name = name

    def eat(self, food):
        return f"{self.name} is eating {food}."

# Subclass: Bird (inherits from Animal)
class Bird(Animal):
    def __init__(self, name, species):
        super().__init__(name)
        self.species = species

    def fly(self):
        return f"{self.name}, a {self.species} bird, is flying high in the sky!"

# Create an instance of Bird
my_bird = Bird("Robin", "American Robin")

# Use methods from the base class and the Bird subclass
print(my_bird.eat("insects"))  # Outputs: "Robin is eating insects."
print(my_bird.fly())           # Outputs: "Robin, a American Robin bird, is flying high in the sky!"
```

### **"is-a" Relationship**

[Inheritance](https://www.boardinfinity.com/blog/types-of-inheritance-in-python/) represents an "**is-a**" connection, implying that a [subclass](https://www.learnpython.dev/03-intermediate-python/30-oop-classes-inheritance/70-inheritance/) is a more specialized form of its [superclass](https://www.stechies.com/inheritance-python/). The base class Vehicle represents a generic vehicle with attributes for make and model and an **info()** method. Two [subclasses](https://www.faceprep.in/python/inheritance-in-python/), Car and Motorcycle, inherit from the base [class](https://textbooks.cs.ksu.edu/cc410/i-oop/06-inheritance-polymorphism/07-python-inheritance/index.html), indicating they are specialized forms of the Vehicle [class](https://dyclassroom.com/python/python-inheritance). They have their constructors, year attribute, and info() method, demonstrating the "**is-a**" relationship.

```python
# Base class: Vehicle
class Vehicle:
    def __init__(self, make, model):
        self.make = make
        self.model = model

    def info(self):
        return f"This is a {self.make} {self.model}."

# Subclass: Car (A Car is a type of Vehicle)
class Car(Vehicle):
    def __init__(self, make, model, year):
        super().__init__(make, model)
        self.year = year

    def info(self):
        return f"This is a {self.year} {self.make} {self.model} car."

# Subclass: Motorcycle (A Motorcycle is a type of Vehicle)
class Motorcycle(Vehicle):
    def __init__(self, make, model, year):
        super().__init__(make, model)
        self.year = year

    def info(self):
        return f"This is a {self.year} {self.make} {self.model} motorcycle."

# Create instances of Car and Motorcycle
my_car = Car("Toyota", "Camry", 2022)
my_motorcycle = Motorcycle("Harley-Davidson", "Sportster", 2021)

# Use the info() method for both Car and Motorcycle
print(my_car.info())           # Outputs: "This is a 2022 Toyota Camry car."
print(my_motorcycle.info())    # Outputs: "This is a 2021 Harley-Davidson Sportster motorcycle."
```

### **Constructor** [**Inheritance**](http://openbookproject.net/books/bpp4awd/ch08.html)

Constructors can be [inherited](https://python-patterns.guide/gang-of-four/composition-over-inheritance/) by [subclasses](https://www.learnpython.dev/03-intermediate-python/30-oop-classes-inheritance/70-inheritance/) from their superclass. If the superclass has a constructor, the subclass can use it to initialize inherited attributes.

### **Multiple** **Inheritance**

Multiple [inheritance](https://www.tutorialsteacher.com/python/inheritance-in-python) is supported by several programming languages, enabling a class to inherit from more than one superclass. This can result in complicated class structures and necessitates careful management of possible conflicts.

### **Abstract Classes**

An abstract [class](https://www.scaler.com/topics/python/polymorphism-in-python/) that cannot be created on its own but offers a common [interface](https://pynative.com/python-polymorphism/) and may include some abstract (unimplemented) methods. These abstract methods must be implemented by [subclasses](https://www.javatpoint.com/polymorphism-in-python) to ensure a consistent interface.

### **Final Classes/Methods**

Some programming languages enable you to declare a [class](https://www.guru99.com/polymorphism-in-python.html) or function as "final," indicating that it cannot be subclassed or overridden further.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><a target="_blank" rel="noopener noreferrer nofollow" href="https://www.educative.io/answers/what-is-class-inheritance-in-python" style="pointer-events: none">Inheritance</a> in OOP creates a structured class hierarchy, improving code organization and efficiency. It promotes reusability, allowing base <a target="_blank" rel="noopener noreferrer nofollow" href="https://www.simplilearn.com/polymorphism-in-python-article" style="pointer-events: none">classes </a>to define common functionality and <a target="_blank" rel="noopener noreferrer nofollow" href="https://www.educative.io/blog/what-is-polymorphism-python" style="pointer-events: none">subclasses </a>to implement <a target="_blank" rel="noopener noreferrer nofollow" href="" style="pointer-events: none">inherited </a>methods.</div>
</div>

## Polymorphism

*"*[*Polymorphism*](https://www.w3schools.com/python/python_polymorphism.asp) *is a fundamental concept in* [*object-oriented programming*](https://www.mygreatlearning.com/blog/polymorphism-in-python/) *(OOP) that allows objects of different classes to be treated as objects of a common superclass."*

Another crucial idea in OOP is [polymorphism](https://www.programiz.com/python-programming/polymorphism), which allows objects of various [classes](https://www.toppr.com/guides/python-guide/tutorials/python-oops/polymorphism-in-python-with-examples/) to be considered as [objects](https://www.codingninjas.com/studio/library/polymorphism-in-python) of a shared [superclass](https://www.analyticsvidhya.com/blog/2021/12/everything-a-beginner-should-know-about-polymorphism-in-pythonwith-examples/). It allows you to work with items based on their common behavior rather than their unique kind.

### Key concepts and terms related to polymorphism

* [**Polymorphism**](https://www.tutorialspoint.com/polymorphism-in-python)
    
* **Common Interface**
    
* **Method Overriding**
    
* **Dynamic Binding**
    
* **Compile-Time** [**Polymorphism**](https://www.cosmiclearn.com/python/polymorphism.php)
    
* **Run-Time Polymorphism**
    
* **Is-a Relationship**
    
* **Abstract Classes and Interfaces**
    
* **Upcasting**
    
* **Downcasting**
    
* **Method Signature**
    

### [**Polymorphism**](https://dongr0510.medium.com/python-object-oriented-programming-polymorphism-feb1ffc3fb4e)

Polymorphism is defined as having "**<mark>many shapes</mark>**" or "**<mark>many forms</mark>**." It enables diverse types of objects to be regarded as though they share a similar interface or a base class.

```python
# Create instances of Dog and Cat
dog = Dog("Buddy")
cat = Cat("Whiskers")

# Create a function that works with Animal objects
def animal_sound(animal):
    return animal.speak()

# Call the function with different objects
print(animal_sound(dog))  # Outputs: "Buddy says Woof!"
print(animal_sound(cat))  # Outputs: "Whiskers says Meow!"
```

### **Common Interface**

[Polymorphism](https://www.digitalocean.com/community/tutorials/how-to-apply-polymorphism-to-classes-in-python-3) is founded on a shared interface or set of methods declared in a superclass and implemented in subclasses. This interface allows objects of different classes to be utilized interchangeably.

### Method Overriding

Subclasses can implement methods inherited from the superclass in their way. This enables objects of various subclasses to respond to the same method call in different ways.

### Dynamic Binding

[Dynamic](https://www.sanfoundry.com/python-questions-answers-polymorphism/) method binding is used in [polymorphism](https://discuss.python.org/t/polymorphism-in-python/25178), where the precise method to be performed is selected at runtime based on the actual object type. This enables method invocation to be more flexible.

### **Compile-Time Polymorphism**

Method overloading, also known as static polymorphism, occurs when many methods with the same name exist in a [class](https://pythonspot.com/polymorphism/) but have distinct argument lists. Based on the inputs supplied, the relevant procedure is called at build time.

### **Run-Time Polymorphism**

Method overriding in subclasses is a type of dynamic [polymorphism](https://www.askpython.com/python/oops/polymorphism-in-python). The method to be executed is determined at runtime based on the type of the real object, allowing for flexibility and extension.

### **Is-a Relationship**

[Polymorphism](https://levelup.gitconnected.com/hidden-power-of-polymorphism-in-python-c9e2539c1633) typically models an "**<mark>is-a</mark>**" relationship, indicating that a subclass is a specialized form of its superclass. For example, a `Circle` is a specialized form of a `Shape`

```python
# Base class: Shape
class Shape:
    def __init__(self, color):
        self.color = color

    def area(self):
        pass

# Subclass: Circle (A Circle is a specialized form of Shape)
class Circle(Shape):
    def __init__(self, color, radius):
        super().__init__(color)
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius * self.radius

# Subclass: Rectangle (A Rectangle is a specialized form of Shape)
class Rectangle(Shape):
    def __init__(self, color, length, width):
        super().__init__(color)
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

# Create instances of Circle and Rectangle
red_circle = Circle("Red", 5.0)
blue_rectangle = Rectangle("Blue", 4.0, 6.0)

# Calculate and display the areas
print(f"Area of the red circle: {red_circle.area()} square units")
print(f"Area of the blue rectangle: {blue_rectangle.area()} square units")
```

### Abstract [Classes](https://www.ibmmainframer.com/python-tutorial/polymorphism/) and [Interfaces](https://www.delftstack.com/howto/python/polymorphism-in-python/)

[Abstract classes](https://www.almabetter.com/bytes/tutorials/python/python-inheritance-and-polymorphism) and interfaces are frequently used to establish common [interfaces](https://aihubprojects.com/polymorphism-in-python/) that may be implemented by various [classes](https://www.gcreddy.com/2022/01/polymorphism-in-python.html). This ensures that the same set of methods is used across all [classes](https://wellsr.com/python/polymorphism-in-python/).

### Upcasting

The technique of treating an [object](https://python-intro.readthedocs.io/en/latest/polymorphism.html) of a [subclass](https://techvidvan.com/tutorials/python-polymorphism/) as an object of its [superclass](https://www.fita.in/polymorphism-in-python/) is known as upcasting. Polymorphism implicitly allows you to work with things at a higher degree of [abstraction](https://codedamn.com/news/python/polymorphism-in-python-with-an-example).

### Downcasting

[Downcasting](https://www.upgrad.com/blog/what-is-polymorphism/) is the inverse of upcasting and entails explicitly transforming a superclass object to a [subclass](https://wiingy.com/learn/python/polymorphism-in-python/) object. To avoid mistakes, it must be done properly and may include type checking.

### Method Signature

The method signature (method name and arguments) of [polymorphic](https://www.learnvern.com/core-python-programming-tutorial/polymorphism-in-python) methods is the same across [subclasses](https://www.shiksha.com/online-courses/articles/all-about-polymorphism-in-python/). Objects of different [classes](https://www.techgeekbuzz.com/blog/polymorphism-in-python/) can therefore be utilized interchangeably.

```python
class Vehicle:
    def __init__(self, brand):
        self.brand = brand

    def drive(self):
        pass

class Car(Vehicle):
    def drive(self):
        return f"{self.brand} car is driving on the road."

class Bicycle(Vehicle):
    def drive(self):
        return f"{self.brand} bicycle is pedaling down the street."

# Create instances of Car and Bicycle
car = Car("Toyota")
bicycle = Bicycle("Schwinn")

# Create a function that simulates driving any vehicle
def simulate_drive(vehicle):
    return vehicle.drive()

# Call the function with different vehicle objects
print(simulate_drive(car))  # Outputs: "Toyota car is driving on the road."
print(simulate_drive(bicycle))  # Outputs: "Schwinn bicycle is pedaling down the street."
```

The Vehicle [class](https://thepythonguru.com/python-inheritance-and-polymorphism/) defines a drive() method, which can be overridden by the Car and Bicycle [subclasses](https://www.studytonight.com/python/python-polymorphism). The simulate\_drive() function simulates driving for a Vehicle object.

<details data-node-type="hn-details-summary"><summary>Summary</summary><div data-type="detailsContent"><a target="_blank" rel="noopener noreferrer nofollow" href="http://www.trytoprogram.com/python-programming/python-inheritance/" style="pointer-events: none">Inheritance</a> is a fundamental concept in <a target="_blank" rel="noopener noreferrer nofollow" href="https://towardsdatascience.com/polymorphism-in-python-fundamentals-for-data-scientists-9dc19071da55" style="pointer-events: none">object-oriented programming </a>(<a target="_blank" rel="noopener noreferrer nofollow" href="https://www.dremendo.com/python-programming-tutorial/python-polymorphism" style="pointer-events: none">OOP</a>) that involves creating new <a target="_blank" rel="noopener noreferrer nofollow" href="https://linuxhint.com/polymorphism_in_python/" style="pointer-events: none">classes </a>based on existing ones, allowing <a target="_blank" rel="noopener noreferrer nofollow" href="https://www.askpython.com/python/oops/polymorphism-in-python" style="pointer-events: none">subclasses </a>to <a target="_blank" rel="noopener noreferrer nofollow" href="https://www.codingninjas.com/studio/library/types-of-inheritance-in-python" style="pointer-events: none">inherit </a>attributes and methods from their <a target="_blank" rel="noopener noreferrer nofollow" href="https://www.faceprep.in/python/polymorphism-in-python/" style="pointer-events: none">superclasses</a>. This promotes code reusability and <a target="_blank" rel="noopener noreferrer nofollow" href="" style="pointer-events: none">class </a>hierarchies. <a target="_blank" rel="noopener noreferrer nofollow" href="https://stackoverflow.com/questions/3724110/practical-example-of-polymorphism" style="pointer-events: none">Polymorphism</a>, on the other hand, allows objects of different <a target="_blank" rel="noopener noreferrer nofollow" href="https://dotnettutorials.net/lesson/polymorphism-in-python/" style="pointer-events: none">classes </a>to be treated as common <a target="_blank" rel="noopener noreferrer nofollow" href="https://datatrained.com/post/polymorphism-in-python/" style="pointer-events: none">superclass </a>objects, enhancing code flexibility and extensibility.</div></details>

Thank you for reading our blog. Our top priority is your success and satisfaction. We are ready to assist with any questions or additional help.

Warm regards,

[**Kamilla Preeti Samuel,**](https://www.linkedin.com/in/preeti-samuel-kamilla-5a247962/)

**Content Editor**

[**ByteScrum Technologies Private Limited!**](https://www.bytescrum.com/)
