Inheritance and Polymorphism in OOP With easy examples.
Inheritance lets a new class (the child) acquire the attributes and methods of an existing class (the parent), then add or change behaviour. A Dog class can inherit everything from an Animal class and only add bark(). Polymorphism means "many forms": the same method call behaves differently depending on the object's actual class, so shelter.feed(animal) works whether the animal is a Dog, Cat or Parrot.
These two ideas matter because they let programs grow without being rewritten. Inheritance captures real "is-a" relationships — a Manager is an Employee — so shared logic lives in one place. Polymorphism lets you write code against the general type and have it automatically do the right thing for every specific type, which is how frameworks stay extensible for decades.
Key Concepts
- Parent / child class: the parent (superclass) defines shared behaviour; the child (subclass) inherits it and may extend or replace parts.
- Is-a relationship: inheritance models genuine categories — a SavingsAccount is a BankAccount. If the sentence sounds wrong, inheritance is the wrong tool.
- Method overriding: the child redefines a parent method with the same signature to specialise behaviour, like Manager overriding calculateBonus().
- Method overloading: same method name with different parameter lists in one class — related to, but different from, overriding.
- Polymorphism: calling speak() on an Animal reference invokes Dog's version for dogs and Cat's for cats — the decision happens at runtime (dynamic dispatch).
- Abstract thinking: code written against the parent type works for every present and future child type without modification.
How It Works
- Building the hierarchy: define Employee with name, salary and a calculatePay() method; define Manager extending Employee, adding a teamSize attribute and overriding calculatePay() to include a bonus.
- Reuse: Manager automatically gets name, salary and every other Employee method without a single duplicated line.
- Specialisation: where Manager needs different behaviour, it overrides just that method; everything else stays inherited.
- Polymorphic payroll: keep all staff in one list of type Employee and loop calling calculatePay() — each object runs its own version, so payroll code never needs updating when a new role like Intern is added.
Worked Example
Compute a monthly payroll using an Employee hierarchy: FullTime staff earn a fixed salary, PartTime staff earn hourly, and Manager extends FullTime with a 10% bonus.
- Asha (FullTime): salary 50,000 → calculatePay() = 50,000.
- Ravi (PartTime): 40 hours × 300 per hour = 12,000 → calculatePay() = 12,000.
- Meera (Manager): base 50,000 plus 10% bonus → 50,000 × 1.10 = 55,000 → calculatePay() = 55,000.
- Total payroll = 50,000 + 12,000 + 55,000 = 117,000.
- The payroll loop holds all three as Employee references and calls the same calculatePay() method — polymorphism selects each person's correct formula automatically, and adding a fourth role later requires zero changes to the loop.
Common Misconceptions
- "Inheritance is just for reusing code." Reuse alone is better served by composition (holding a helper object). Inheritance's real purpose is substitutability: a child must be usable wherever the parent is expected.
- "Overriding and overloading are the same." Overriding redefines an inherited method with the identical signature in the child class; overloading defines multiple same-named methods with different parameters in one class.
- "Deep inheritance hierarchies are good design." Hierarchies deeper than two or three levels become rigid and confusing — a change at the top ripples unpredictably downward. Prefer shallow hierarchies and composition.
Real-World Applications
- GUI frameworks: Button, TextBox and Window all extend a Widget class, so layout code treats every control uniformly.
- Games: Player, Enemy and Projectile extend GameEntity; the game loop updates them all through one polymorphic call.
- Payment systems: CardPayment and UPIPayment extend Payment, letting checkout code process any method identically.
- File systems: File and Directory both behave as filesystem nodes, so copy and delete work recursively without special cases.
Inheritance organises what things are, polymorphism organises what they do. Model true is-a relationships, override only what genuinely differs, and write code against the general type — then new kinds of objects slot into old code without breaking it.
Related blogs
- Classes, Objects and Constructors: Complete Beginner's Guide
- Encapsulation and Abstraction: Complete Beginner's Guide
- Interfaces and Abstract Classes: Complete Beginner's Guide
- Exception Handling: Complete Beginner's Guide For students.
- Collections frameworks (Java/C++) Explained with Examples
- Multithreading Basics: Complete Beginner's Guide Guide.