Chapter III Inheritance in Python

inheritance in python

A Comprehensive Guide with Real-World Banking Examples

Inheritance is a powerful concept in object-oriented programming (OOP) that allows one class to inherit the attributes and methods of another class. This feature makes it easier to create reusable, modular, and maintainable code, especially in large-scale applications. Inheritance in Python, is a key component of the OOP paradigm, enabling developers to extend functionality and reduce code redundancy.

This article will provide an in-depth look at inheritance in Python, how it works, its various forms, and real-world use cases. We will particularly focus on the Python 3.12 implementation and demonstrate real-world examples from the banking sector to make the concept more relatable.

To maintain continuity, please check our previous chapter about classes here.


Table of Contents

  1. What is Inheritance in Python?
  2. How to Implement Inheritance in Python?
  3. Types of Inheritance in Python
  4. Real-World Banking Examples for Each Type of Inheritance
  5. Method Overriding and super()
  6. The Importance of Inheritance in Python
  7. Best Practices for Using Inheritance
  8. Conclusion

1. What is Inheritance in Python?

Inheritance in Python is a mechanism that allows one class (the child or derived class) to inherit properties (attributes and methods) from another class (the parent or base class). This enables a child class to reuse the code of the parent class, and at the same time, extend or modify it to suit specific needs.

Inheritance brings several benefits:

  • Code Reusability: You can use existing code to create new functionalities.
  • Modularity: It allows for cleaner, modularized code.
  • Extendability: You can add or modify features without disrupting the base class.

2. How to Implement Inheritance in Python?

Basic Syntax

The syntax for creating a child class that inherits from a parent class in Python is straightforward.

SKMEI Men’s Watch

New Wheels Rolling Creative Fashion Che Youhui League Fans Butterfly Double Snap Gift Wristwatch – 1787

Less Discount -79% ₹1,449

class ParentClass:

    # Parent class code

class ChildClass(ParentClass):

    # Child class code

Example

Let’s create a simple example to illustrate basic inheritance in Python.

python
# Parent class

class BankAccount:

    def __init__(self, account_number, balance):

        self.account_number = account_number

        self.balance = balance

    def deposit(self, amount):

        self.balance += amount

        return f"Deposited {amount}. New balance is {self.balance}"

    def withdraw(self, amount):

        if self.balance >= amount:

            self.balance -= amount

            return f"Withdrew {amount}. New balance is {self.balance}"

        else:

            return "Insufficient balance."

# Child class inheriting from BankAccount

class SavingsAccount(BankAccount):

    def __init__(self, account_number, balance, interest_rate):

        super().__init__(account_number, balance)

        self.interest_rate = interest_rate

    def add_interest(self):

        interest = self.balance * self.interest_rate / 100

        self.balance += interest

        return f"Interest added. New balance is {self.balance}"

# Creating an instance of the child class

account = SavingsAccount("123456789", 1000, 5)

print(account.deposit(500))  # Output: Deposited 500. New balance is 1500

print(account.add_interest())  # Output: Interest added. New balance is 1575.0

In the above example, the SavingsAccount class inherits methods (deposit, withdraw) and attributes (account_number, balance) from the BankAccount class. Additionally, the child class (SavingsAccount) has its own method add_interest.


3. Types of Inheritance in Python

Python supports different types of inheritance to cater to various design needs. These include:

  1. Single Inheritance
  2. Multiple Inheritance
  3. Multilevel Inheritance
  4. Hierarchical Inheritance
  5. Hybrid Inheritance

3.1. Single Inheritance

Single Inheritance is when a class inherits from one parent class. It’s the simplest form of inheritance.

Syntax:

class Parent:

    pass

class Child(Parent):

    pass

Example:

class Loan:

    def __init__(self, loan_id, amount):

        self.loan_id = loan_id

        self.amount = amount

class PersonalLoan(Loan):

    def __init__(self, loan_id, amount, borrower_name):

        super().__init__(loan_id, amount)

        self.borrower_name = borrower_name

loan = PersonalLoan("LN12345", 10000, "Alice")

print(f"Loan ID: {loan.loan_id}, Borrower: {loan.borrower_name}")

Real-World Banking Example:

Imagine a banking system where different types of loans are offered. Each loan type (personal loan, home loan, car loan) inherits from the base class Loan. This would help the bank to have a standard way of managing loan-related functionalities like calculating interest, retrieving loan details, etc.

3.2. Multiple Inheritance

Multiple Inheritance is when a class inherits from more than one parent class. Python supports multiple inheritance, unlike some other programming languages.

Syntax:

class Parent1:

    pass

class Parent2:

    pass

class Child(Parent1, Parent2):

    pass
code

Example:

class Loan:

    def __init__(self, loan_id, amount):

        self.loan_id = loan_id

        self.amount = amount

class Customer:

    def __init__(self, name):

        self.name = name

class LoanAccount(Loan, Customer):

    def __init__(self, loan_id, amount, name):

        Loan.__init__(self, loan_id, amount)

        Customer.__init__(self, name)

loan_account = LoanAccount("LN56789", 50000, "Bob")

print(f"Loan ID: {loan_account.loan_id}, Customer: {loan_account.name}")

Real-World Banking Example:

In the banking sector, LoanAccount could be an example of multiple inheritance, where Loan and Customer serve as the two parent classes. This allows the bank to manage loans associated with customers, combining the attributes of both the Loan class (e.g., loan amount, interest rate) and Customer class (e.g., customer name, contact details).

3.3. Multilevel Inheritance

Multilevel Inheritance occurs when a class is derived from another derived class, forming a chain of inheritance.

Syntax:

class GrandParent:

    pass

class Parent(GrandParent):

    pass

class Child(Parent):

    pass

Example:

class Bank:

    def __init__(self, bank_name):

        self.bank_name = bank_name

class Branch(Bank):

    def __init__(self, bank_name, branch_name):

        super().__init__(bank_name)

        self.branch_name = branch_name

class Employee(Branch):

    def __init__(self, bank_name, branch_name, employee_name):

        super().__init__(bank_name, branch_name)

        self.employee_name = employee_name

emp = Employee("Global Bank", "Main Branch", "John Doe")

print(f"Bank: {emp.bank_name}, Branch: {emp.branch_name}, Employee: {emp.employee_name}")

Real-World Banking Example:

In a banking scenario, a large bank like Global Bank may have multiple branches, and each branch will have employees. The class Employee inherits from Branch, and Branch inherits from Bank. This structure allows for multilevel inheritance, representing the hierarchy in a banking institution.

3.4. Hierarchical Inheritance

Hierarchical Inheritance occurs when multiple child classes inherit from the same parent class.

Syntax:

class Parent:

    pass

class Child1(Parent):

    pass

class Child2(Parent):

    pass

Example:

class BankAccount:

    def __init__(self, account_number, balance):

        self.account_number = account_number

        self.balance = balance

class CheckingAccount(BankAccount):

    def __init__(self, account_number, balance, overdraft_limit):

        super().__init__(account_number, balance)

        self.overdraft_limit = overdraft_limit

class SavingsAccount(BankAccount):

    def __init__(self, account_number, balance, interest_rate):

        super().__init__(account_number, balance)

        self.interest_rate = interest_rate

Real-World Banking Example:

In the banking domain, you might have several types of accounts, such as CheckingAccount and SavingsAccount, both inheriting from a base class BankAccount. This type of inheritance structure allows you to define common behaviors (like deposit, withdraw) in the base class, while specific behaviors (like overdraft limit or interest rate) can be defined in the derived classes.

3.5. Hybrid Inheritance

Hybrid Inheritance is a combination of two or more types of inheritance, such as a mix of multiple inheritance and multilevel inheritance.

Syntax:

class Parent:

    pass

class Child1(Parent):

    pass

class Child2(Parent):

    pass

class GrandChild(Child1, Child2):

    pass

Hybrid inheritance is typically avoided if possible due to its complexity, but it is useful in certain cases where a more flexible design is needed.


4. Real-World Banking Example Scenarios for Each Type of Inheritance

Here’s how each type of inheritance might be used in a real-world banking system:

  1. Single Inheritance: A LoanAccount class that extends the Loan class to add more specialized features like calculating penalties.
  2. Multiple Inheritance: A LoanCustomer class that inherits from both Loan and Customer classes to provide features like generating loan statements for a customer.
  3. Multilevel Inheritance: An employee system where an Employee class inherits from a Branch class, which in turn inherits from a Bank class, representing the hierarchy within the bank.
  4. Hierarchical Inheritance: Different types of bank accounts (like savings and checking accounts) inheriting from a base BankAccount class.
  5. Hybrid Inheritance: In large-scale systems, some complex business logic may require hybrid inheritance to combine features from multiple classes and different layers of inheritance.

5. Method Overriding and super()

Method Overriding

When a method in a child class has the same name as a method in the parent class, the method in the child class will override the parent method. This is useful when you want to extend or modify the behavior of a method inherited from a parent class.

Example:

class BankAccount:

    def display_info(self):

        return "This is a general bank account."

class SavingsAccount(BankAccount):

    def display_info(self):

        return "This is a savings account with an interest rate."

Here, display_info() in SavingsAccount overrides the method in BankAccount.

Using super()

The super() function in Python is used to call methods from the parent class. It is especially useful when you want to invoke the parent class’s __init__ method within the child class.

Example:

class BankAccount:

    def __init__(self, account_number, balance):

        self.account_number = account_number

        self.balance = balance

class CheckingAccount(BankAccount):

    def __init__(self, account_number, balance, overdraft_limit):

        super().__init__(account_number, balance)  # Calling parent class's __init__

        self.overdraft_limit = overdraft_limit

6. The Importance of Inheritance in Python

Inheritance is essential in Python programming because it enables:

  1. Code Reusability: By defining common functionality in a parent class, it can be reused in multiple child classes.
  2. Modularity: Inheritance allows you to break down complex systems into smaller, more manageable classes.
  3. Extendability: Developers can extend existing code without rewriting it, allowing for easy maintenance and updates.
  4. Readability and Maintenance: Inheritance helps keep the code clean, organized, and readable, making it easier to debug and maintain.

7. Best Practices for Using Inheritance

  1. Favor Composition Over Inheritance: Sometimes it’s better to compose objects (by including instances of other classes as attributes) rather than relying solely on inheritance.
  2. Use super() Wisely: Always use super() when overriding methods in child classes, especially when dealing with multiple inheritance.
  3. Don’t Overuse Inheritance: Avoid creating very deep inheritance chains as they can make the code harder to understand and maintain.
  4. Test Extensively: Ensure that inherited methods work correctly with the child class modifications. Testing is crucial in large systems like banking applications.

8. Conclusion

Inheritance in Python is a cornerstone of object-oriented programming and plays a crucial role in creating robust, maintainable, and scalable applications. Whether it’s a small banking system or a complex enterprise-grade financial solution, inheritance allows you to reuse code, minimize redundancy, and organize functionality efficiently.

By using real-world examples from the banking sector, we’ve demonstrated how different types of inheritance can be applied to solve real-world problems. Understanding and leveraging inheritance, along with best practices like method overriding and super(), will help you design clean and efficient Python applications.

Curated course

Dhakate Rahul

Dhakate Rahul

Leave a Reply

Your email address will not be published. Required fields are marked *