Page Content

Tutorials

Inheritance and Polymorphism in Python With Example?

Inheritance and polymorphism

Inheritance and polymorphism
Inheritance and polymorphism

Polymorphism and inheritance are fundamental OOP concepts. OOP constructs objects from linked data (attributes) and actions (methods). Instead of beginning from scratch or altering existing code, it enables developers to customise it and factor code to reduce repetition while creating new systems.

Inheritance

OOP requires inheritance to create new classes from existing ones. This method lets one class inherit traits and behaviours from another. Software customisation and reusability are the main objectives of inheritance. You can define a new class by inheriting from an existing one with minimal or no modifications. The original class is referred to as the parent class, superclass, or base class in an inheritance relationship. The child class, subclass, or derived class is the new class that inherits from the parent. Frequently, both terms are used interchangeably.

The superclass name is enclosed in parenthesis after the subclass name in the class definition when defining a subclass in Python. Class SubClass(SuperClass): appears to be the syntax. If no other parent is supplied, Python 3 will automatically use object as the parent class when you define a new class.

All of the characteristics and methods specified for the parent class are passed down to the subclass. Next, the kid class can:

  • Direct access to inherited methods and attributes.
  • Include new characteristics and code.
  • Override properties and code that are inherited.

Overriding inherited methods changes their behaviour. Create a subclass method with the same name as the superclass method. This can be done by overriding init(). The super() function allows you to access the parent class’s methods or obtain assistance from them. For example, to correctly initialise the parent component of the object, you may call super().init(base class parameters).

The best way to model “is-a” relationships between classes is through inheritance. A “Dog is an Animal” is one example.

Types of Inheritance Including:

Single inheritance: There is only one superclass from which a class can inherit.

Multiple inheritance: A class has several superclasses from which it inherits. Although this is helpful for combining packages of class-based code, it can be intricate and delicate, which may result in the “diamond problem” of ambiguity.

Multilevel inheritance: A chain is created when a subclass becomes the superclass for another class.

Hierarchical inheritance: One superclass is the ancestor of several classes.

Inheritance is useful for customising and reusing code, but too much use can make applications difficult to maintain. Aggregation and composition techniques are frequently suggested as substitutes or enhancements, particularly for “has-a” relationships (e.g., an employee “has a” laptop).

Polymorphism

Another essential OOP principle is polymorphism. Greek words that mean “many forms”. It refers to the idea in programming that a single name can stand for several functions. The ability to communicate with different objects using the same message (such as calling a method) and have each object react differently is known as polymorphism. The class of the object determines the precise behaviour. This enables you to request the same action from a variety of various kinds of objects.

Polymorphism and method overriding are closely related in the context of inheritance. Python chooses which particular version of a method to run at runtime depending on the kind of object the method is called on if the function is implemented in various classes inside an inheritance hierarchy (either inherited or overridden). We call this procedure dynamic binding.

You can send an instance of a subclass to a parameter that expects an instance of a superclass with polymorphism. The version of the method that is unique to the object’s actual class (the subclass) will be used when it is called on this object. This feature is a key factor in Python’s adaptability.

The str() function, which enables many object types to offer a printed string representation using the same method name, is a typical illustration of polymorphism. Another illustration is operator overloading, in which the types of operands that an operator (such as + or *) is used with determine its meaning. for instance, can denote repetition for strings and multiplication for numbers. One particular example of polymorphism is operator overloading.

Code Example Demonstrating Inheritance and Polymorphism:

Inspired by the examples of automobiles and animals creating noises, let’s use a Python programming example to demonstrate these ideas.

# Base class (Superclass) demonstrating a general concept
class Vehicle:
    # init method to initialize objects of this class
    def init (self, model):
        self.model = model # An attribute of the class 
    # Method representing a general behavior of vehicles
    def vehicle model(self):
        print(f"Vehicle Model name is {self.model}")
# Derived class (Subclass) inheriting from Vehicle 
# Car is a type of Vehicle (is-a relationship) 
class Car(Vehicle):
    # Car inherits the init and vehicle model methods from Vehicle
    # We can add new attributes or methods specific to Car
    def init (self, model, fuel_type):
        # Call the parent class's  init  using super() 
        super(). init (model)
        self.fuel type = fuel type # New attribute specific to Car
    # We could also override vehicle model here if needed, but let's keep it simple
    # and show polymorphism through a different method.
    def start engine(self):
        print(f"{self.model} Car engine started (Fuel: {self.fuel type}).")
# Another Derived class inheriting from Vehicle
# Bike is a type of Vehicle (is-a relationship)
class Bike(Vehicle):
    # Bike inherits the init  and vehicle model methods from Vehicle
    # We can add new attributes or methods specific to Bike
    def init (self, model, bike type):
        super(). init (model)
        self.bike type = bike type # New attribute specific to Bike
    def wheelie(self):
        print(f"{self.model} {self.bike type} is doing a wheelie!")
# Function demonstrating Polymorphism
# This function works with any object that is a Vehicle or inherits from Vehicle
def describe vehicle(vehicle obj):
    # Call a method that might be implemented differently (polymorphic behavior)
    vehicle obj.vehicle model() # Calls the appropriate vehicle model based on object type 
    # Call other methods specific to the object type if available (e.g., using isinstance or try-except)
    # Or call common methods defined in the base class
# Create instances of the classes 
my car = Car("Sedan", "Petrol")
my bike = Bike("Cruiser", "Motorcycle")
# A generic vehicle instance
generic vehicle = Vehicle("Generic Transport")
# Demonstrate inheritance: Accessing inherited attributes and methods
print(f"Car model: {my car.model}") # Accesses inherited attribute 'model' 
my car.vehicle model() # Calls inherited method vehicle model 
print(f"Bike model: {my bike.model}")
my bike.vehicle model()
# Demonstrate polymorphism: Pass different types of Vehicle objects to the same function 
print("\n Describing Vehicles ")
describe vehicle(generic vehicle)
describe vehicle(my car) # Car object is treated as a Vehicle
describe vehicle(my bike) # Bike object is treated as a Vehicle
# Demonstrate methods specific to subclasses
my car.start engine() # Only Car objects have start engine
my bike.wheelie() # Only Bike objects have wheelie 

The Vehicle class is the ancestor of the Car and Bike classes in this instance. They immediately obtain the vehicle model method and the model attribute from Vehicle. Additionally, they specify their own unique procedures (start engine, wheelie) and characteristics (fuel type, bike type). The function describe vehicle exhibits polymorphism. Any object that is a Vehicle or a subclass of a Vehicle can be accepted by it. Python’s dynamic binding makes sure that the appropriate vehicle model method is used depending on the kind of object given to the function when vehicle obj.vehicle model() is invoked inside the function.

If Car or Bike had overridden vehicle model, the function would automatically call the overridden version for instances of those classes. However, in this particular instance, the vehicle model method was not overridden in the subclasses, so the version from the Vehicle base class is always called. This enables the function to perform properly with many vehicle object types without requiring prior knowledge of their particular subclass.

Kowsalya
Kowsalya
Hi, I'm Kowsalya a B.Com graduate and currently working as an Author at Govindhtech Solutions. I'm deeply passionate about publishing the latest tech news and tutorials that bringing insightful updates to readers. I enjoy creating step-by-step guides and making complex topics easier to understand for everyone.
Index