Challenges with Inheritance

Inheritance can simplify code by sharing behavior between classes, but it often introduces challenges that make systems harder to understand, extend, and maintain. Let's examine the key issues with inheritance and explore real-world examples.

Issue 1: Tight Coupling

Inheritance creates a tight relationship between parent and child classes. Changes to the parent class can ripple through all subclasses, causing unintended side effects.

      Tight Coupling Example:
      ┌───────────┐
      │ BaseClass │
      └─────┬─────┘
            ↓
      ┌───────────┐
      │ SubClass  │
      └───────────┘

Example:

class User
  def initialize(name)
    @name = name
  end

  def display_name
    @name.upcase
  end
end

class AdminUser < User
  def display_name
    super + " [ADMIN]"
  end
end

admin = AdminUser.new("Alice")
puts admin.display_name
# Output: "ALICE [ADMIN]"
        

If the `User` class changes its `display_name` implementation, all subclasses may break or behave unexpectedly.

Issue 2: Rigidity

Inheritance hierarchies often become rigid, making it difficult to add new features without modifying existing classes.

        Rigid Hierarchy:
          ┌─────────────┐
          │ Animal      │
          └─────┬───────┘
                ↓
          ┌─────────────┐
          │ Mammal      │
          └─────┬───────┘
                ↓
          ┌─────────────┐
          │ Human       │
          └─────────────┘

Example:

class Animal
  def speak
    "Generic sound"
  end
end

class Mammal < Animal
  def speak
    "Mammal sound"
  end
end

class Human < Mammal
  def speak
    "Hello"
  end
end

Human.new.speak # Output: "Hello"
        

Adding a new type of mammal that doesn’t fit this hierarchy (e.g., `Platypus`) may require significant refactoring.

Issue 3: Duplicate Logic

Subclasses often end up reimplementing similar logic, defeating the purpose of inheritance.

      Duplicate Logic Example:
          ┌───────────┐
          │ Employee  │
          └─────┬─────┘
                ↓
        ┌──────────────┐
        │ Manager      │
        └──────────────┘
        ┌──────────────┐
        │ Developer    │
        └──────────────┘

Example:

class Employee
  def initialize(name)
    @name = name
  end

  def bonus
    1000
  end
end

class Manager < Employee
  def bonus
    super + 2000
  end
end

class Developer < Employee
  def bonus
    super + 1500
  end
end
        

Each subclass implements a custom `bonus` method, duplicating logic instead of sharing it in a common place.

Conclusion

Inheritance is a valuable tool, but its limitations make it unsuitable for many situations. By understanding these challenges, we can better appreciate the benefits of composition, which we’ll explore in the next section.

Continue to the Solution Section →