Opening Scenario

You started a notification system. It had one class:

// Java
class Notifier {
    void send(String to, String message) { /* ... */ }
}

Then product asked for SMS notifications. You made SmsNotifier extends Notifier. Then Slack — SlackNotifier extends Notifier. Then: "send the same notification via email AND SMS." You created EmailAndSmsNotifier extends Notifier. Then: "retry on failure." Now you have RetryingEmailNotifier extends EmailNotifier, RetryingSmsNotifier extends SmsNotifier, RetryingEmailAndSmsNotifier extends EmailAndSmsNotifier.

Nine classes, the hierarchy is a tangle, and product just asked for "rate-limited retrying email AND Slack, but only in the EU region."

Every senior engineer you ask says the same thing: "favor composition over inheritance." What does that actually mean, and when is inheritance still right?


Question Progression

Q1: What does inheritance actually give you, and what does it cost?

Question: class Dog extends Animal — what exactly does the subclass get? And what commitment have you made by using extends?

Reasoning: Inheritance…

In the full tutorial

  • When to Reach for This

Glossary history

Click dotted jargon to save explanations here.