Inheritance lets a class (the subclass or child) reuse and extend the fields and methods of another class (the superclass or parent). It models an is-a relationship: a Dog is an Animal.
Inheritance lets a class (the subclass or child) reuse and extend the fields and methods of another class (the superclass or parent). It models an is-a relationship: a Dog is an Animal.
class Animal:
def __init__(self, name):
self.name = name
def eat(self):
return f"{self.name} is eating"
class Dog(Animal): # Dog inherits everything from Animal
def bark(self): # ...and adds new behavior
return "Woof!"
d = Dog("Rex")
print(d.eat()) # "Rex is eating" → inherited, not rewritten
print(d.bark()) # "Woof!" → Dog-specific
Dog got __init__ and eat for free and added bark. A subclass can also override inherited methods to change behavior.
| Benefit | Risk |
|---|---|
| Reuse shared code | Tight coupling to the parent |
| Model real hierarchies | Fragile base class — parent changes break children |
| Polymorphism via a common type | Deep trees become hard to follow |
A common guideline: favor composition over inheritance when the relationship is really "has-a," not "is-a."
Inheritance is the most-misused OOP feature: it's tempting to use it just to share code, which couples unrelated classes.
Used correctly — only for genuine is-a relationships — it gives you reuse plus polymorphism, letting you treat many subtypes uniformly through their common parent.