Inheritance is a powerful concept in Object-Oriented Programming (OOP) that allows a class (called a child class) to inherit attributes and methods from another class (called a parent class). This promotes code reusability and makes it easier to create and maintain complex programs. In this tutorial, we’ll cover inheritance with practical examples. We’ll also explain the role of super() in inheritance.
1. What is super()?
The super() function is used to call a method from the parent class. It is commonly used in the __init__ method of a child class to ensure that the parent class’s __init__ method is called. This is important when the child class adds new attributes but still needs to initialize the attributes inherited from the parent class.
Key Points About super()
- Purpose: To call a method (usually __init__) from the parent class.
- When to Use: When the child class has its own __init__ method and needs to initialize inherited attributes.
- How It Works: super().__init__(...) calls the parent class’s __init__ method.
2. Example_1: Modeling Shapes with Inheritance
Let’s start with a practical example where we model shapes. The parent class Shape provides a color attribute, and the child classes Rectangle and Circle use or modify it while calculating areas.
Parent Class: Shape
class Shape:
def __init__(self, color):
self.color = color # Inherited property
def area(self):
return 0 # Default area for a generic shape
def describe(self):
return f"This is a {self.color} shape with area {self.area()}"
Child Class: Rectangle
class Rectangle(Shape):
def __init__(self, color, length, width):
super().__init__(color) # Inherit color from Shape, Call parent's __init__ to initialize color
self.length = length
self.width = width
def area(self): # Override parent's area method
return self.length * self.width
def change_color(self, new_color): # Modify inherited color
self.color = new_color
return f"Rectangle color changed to {self.color}"
Child Class: Circle
class Circle(Shape):
def __init__(self, color, radius):
super().__init__(color) # Inherit color from Shape
self.radius = radius
def area(self): # Override parent's area method
return 3.14 * self.radius * self.radius
def describe(self): # Override parent's describe method
return f"This is a {self.color} circle with area {self.area():.2f}"
Using the Classes
# Create objects with numbers
rect = Rectangle("Blue", 4, 5)
circ = Circle("Red", 3)
# Test using inherited color and numeric calculations
print(rect.describe()) # Output: This is a Blue shape with area 20
print(rect.change_color("Green")) # Output: Rectangle color changed to Green
print(rect.describe()) # Output: This is a Green shape with area 20
print(circ.describe()) # Output: This is a Red circle with area 28.26
Explanation of the Shape Example
Parent Class (Shape):
- Defines a color attribute that is inherited by child classes.
- Provides a default area method (returns 0 for a generic shape).
- Has a describe method that uses the inherited color and area.
Child Class (Rectangle):
- Inherits color and uses it in the describe method.
- Adds length and width attributes to calculate the area (length * width).
- Uses super().__init__(color) to initialize the inherited color attribute.
- Includes a change_color method to modify the inherited color.
Child Class (Circle):
- Inherits color and uses it in an overridden describe method.
- Adds a radius attribute to calculate the area (3.14 * radius * radius).
- Uses super().__init__(color) to initialize the inherited color attribute.
Numeric Breakdown:
- Rectangle: length = 4, width = 5 → Area = 4 * 5 = 20.
- Circle: radius = 3 → Area = 3.14 * 3 * 3 = 28.26.
Role of super():
- In both Rectangle and Circle, super().__init__(color) ensures that the color attribute is initialized by the Shape class.
- Without super(), the color attribute would not be initialized, and the program would throw an error.
3. Example_2: Inheritance with Numeric Calculations
Now, let’s explore another example involving numeric calculations to further solidify your understanding of inheritance and super().
Parent Class: Calculator
class Calculator:
def __init__(self, a, b):
self.a = a
self.b = b
def add(self):
return self.a + self.b
def subtract(self):
return self.a - self.b
Child Class: AdvancedCalculator
class AdvancedCalculator(Calculator):
def multiply(self):
return self.a * self.b
def divide(self):
if self.b != 0:
return self.a / self.b
else:
return "Division by zero is not allowed!"
Using the Classes
# Create an instance of AdvancedCalculator
calc = AdvancedCalculator(10, 5)
# Use methods from both parent and child classes
print("Addition:", calc.add()) # Output: Addition: 15
print("Subtraction:", calc.subtract()) # Output: Subtraction: 5
print("Multiplication:", calc.multiply()) # Output: Multiplication: 50
print("Division:", calc.divide()) # Output: Division: 2.0
Explanation of the Calculator Example
Parent Class (Calculator):
- Defines basic arithmetic operations (add and subtract).
- Initializes two numbers (a and b).
Child Class (AdvancedCalculator):
- Inherits add and subtract methods from Calculator.
- Adds advanced operations like multiply and divide.
- Why super() Wasn’t Used in AdvancedCalculator
In the AdvancedCalculator class, we didn’t use super() because the parent class (Calculator) already initializes the attributes a and b in its __init__ method. When the AdvancedCalculator class inherits from Calculator, it automatically gains access to all the attributes and methods of the parent class, including a and b.
- Key Difference Between the Two Examples
— Example 1: Rectangle Class
In the Rectangle class, we added new attributes (length and width) in addition to inheriting the color attribute from the Shape class. Since the child class (Rectangle) has its own __init__ method, we need to explicitly call the parent class’s __init__ method using super() to initialize the inherited color attribute.
— Example 2: AdvancedCalculator Class
In the AdvancedCalculator class, we did not add any new attributes. It simply inherits the a and b attributes from the Calculator class. Since the child class (AdvancedCalculator) doesn’t have its own __init__ method, Python automatically calls the parent class’s __init__ method to initialize a and b.
4. Challenge for Readers
Problem: Create a BankAccount class with attributes account_number and balance. Then, create a SavingsAccount class that inherits from BankAccount and adds an attribute interest_rate. Finally, create a FixedDeposit class that inherits from BankAccount and adds an attribute duration.
Solution:
class BankAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.balance = balance
def display_balance(self):
return f"Account {self.account_number} has a balance of ${self.balance}."
class SavingsAccount(BankAccount):
def __init__(self, account_number, balance, interest_rate):
super().__init__(account_number, balance) # Call parent's __init__
self.interest_rate = interest_rate # Add new attribute
def calculate_interest(self):
return self.balance * self.interest_rate / 100
class FixedDeposit(BankAccount):
def __init__(self, account_number, balance, duration):
super().__init__(account_number, balance) # Call parent's __init__
self.duration = duration # Add new attribute
def display_duration(self):
return f"Fixed Deposit Account {self.account_number} has a duration of {self.duration} months."
# Example usage
savings = SavingsAccount("SA123", 1000, 5)
fixed_deposit = FixedDeposit("FD456", 5000, 12)
print(savings.display_balance()) # Output: Account SA123 has a balance of $1000.
print("Interest:", savings.calculate_interest()) # Output: Interest: 50.0
print(fixed_deposit.display_balance()) # Output: Account FD456 has a balance of $5000.
print(fixed_deposit.display_duration()) # Output: Fixed Deposit Account FD456 has a duration of 12 months.
By practicing these examples, you’ll gain a solid understanding of inheritance in Python.
'Python Intermediate and Advanced' 카테고리의 다른 글
Python Intermediate_012:Python’s Magic Methods in Classes(Overview) (0) | 2025.04.05 |
---|---|
Python Intermediate_011: Recursive Functions in Python (0) | 2025.04.05 |
Python Intermediate_009: Lambda Functions in Python (0) | 2025.04.05 |
Python Intermediate_008: Understanding Generators in Python (0) | 2025.03.10 |
Python Intermediate_007: Understanding @property and Setter Decorators in Python (0) | 2025.03.09 |