Inheritance

Why rewrite code when you can inherit it? Master the IS-A relationship to build efficient and scalable object hierarchies.

April 19, 20264 min read6 / 14

In the world of software, we hate repeating ourselves. If two things are 90% similar, we shouldn't write the same code twice. This is the core idea behind the second pillar of OOP: Inheritance.

The Essentials

The "Family Tree" guide to this post:

  1. The IS-A Rule: Inheritance should only be used when you can say "B is a type of A" (e.g., a Dog IS-A Animal).
  2. Code Reuse: Children automatically get all the non-private attributes and behaviors of their parents.
  3. Extensibility: You can add new features to a child without touching the parent's code.
  4. The "extends" Keyword: In Java and TS, we use extends to link a child to its parent.

The IS-A Relationship

Before you use inheritance, ask yourself: Is this a type of that?

  1. Valid: A SmartPhone is a type of Phone. (Inheritance)
  2. Invalid: A Car has a Wheel. (This is Association, not inheritance).

If you use inheritance for "Has-A" relationships, your code will quickly become a messy "ball of thread."

Inheritance in Action: The Hierarchy Problem

Code Duplication

Without inheritance, you copy the same fields (name, email) into every class. Changing the email logic means updating 10 files.

class Student { name; email; }
class Mentor { name; email; }
class Admin { name; email; }

This is "WET" code (Write Everything Twice). It is a maintenance nightmare.

Smart Inheritance

We extract common data into a User parent. Children only define what makes them unique.

class User { name; email; }

class Student extends User { .. }
class Mentor extends User { .. }

The "IS-A" relationship ensures code reuse and logical grouping across the system.

Code Implementation: The "IS-A" Relationship

Here is how you link a child to its parent to inherit attributes and actions:

class User { name: string; email: string; login() { console.log(`${this.name} logged in.`); } } // Instructor IS-A User class Instructor extends User { batchName: string; // Gains name, email, and login() for free! scheduleClass() { console.log(`Class scheduled for ${this.batchName}`); } } const instr = new Instructor(); instr.name = "Denver"; // Inherited instr.login(); // Inherited

Why Inheritance Wins

  1. Centralized Logic: If you need to change how login() works, you change it once in the User class, and every type of user (Student, Instructor, Mentor) gets the update instantly.
  2. Polymorphism (Preview): You can treat an Instructor as a User, allowing you to write general code that works for any type of person in your system.

Inheritance is powerful, but it brings a mystery: what happens to private data when a child inherits? Let's find out in The Inheritance Mystery.

Practice what you just read.

Inheritance: The Reference QuizLab: Vehicle Hierarchy
2 exercises