Writing a class definition with a parent class in parentheses makes the child inherit every attribute and method from that parent automatically — an instance of the child can call any method defined on the parent without redefining it. A subclass can override a parent's method by defining a method with the same name, and it can extend rather than fully replace the parent's behavior by calling super().method(...) inside the override, which explicitly invokes the parent's version. Python also supports multiple inheritance, where a class inherits from more than one parent at once, though it's used sparingly due to added complexity.
1Understanding Inheritance
Writing a class definition with a parent class in parentheses makes the child inherit every attribute and method from that parent automatically — an instance of the child can call any method defined on the parent without redefining it. A subclass can override a parent's method by defining a method with the same name, and it can extend rather than fully replace the parent's behavior by calling super().method(...) inside the override, which explicitly invokes the parent's version. Python also supports multiple inheritance, where a class inherits from more than one parent at once, though it's used sparingly due to added complexity.
Reach for inheritance specifically for a genuine 'is-a' relationship, like a Dog being an Animal; for a 'has-a' relationship, like a Car having an Engine, composition — storing an instance of one class inside another — is usually the cleaner design.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
print(Dog("Rex").speak())2Practical Example
Here is a real-world application of Inheritance showing how it is used in production Python code.
class Employee:
def __init__(self, name, salary):
self.name = name
self.salary = salary
class Manager(Employee):
def __init__(self, name, salary, team_size):
super().__init__(name, salary)
self.team_size = team_size
m = Manager("Ana", 90000, 5)
print(m.name, m.team_size)3Best Practices
Follow these guidelines when working with Inheritance:
1. Use inheritance only for genuine is-a relationships; prefer composition when one object simply uses or contains another
2. Call super().__init__(...) in a subclass's constructor so the parent class's setup still runs
3. Keep base classes focused and stable — changing a widely-inherited-from parent class can ripple unpredictably through every subclass
Tip: Reach for inheritance specifically for a genuine 'is-a' relationship, like a Dog being an Animal; for a 'has-a' relationship, like a Car having an Engine, composition — storing an instance of one class inside another — is usually the cleaner design.
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
print(Dog("Rex").speak())