What is the Decorator pattern and how does it differ from inheritance?

The Decorator pattern adds behavior to individual objects dynamically at runtime by wrapping them, whereas inheritance adds behavior to an entire class hierarchy at compile time. Decorator targets specific instances; inheritance targets every instance of a subclass.

Key Points: • Decorator applies behavior per object instance; inheritance applies behavior to every instance of the subclass. • Decorator composes behavior at runtime; inheritance fixes behavior at compile time. • Multiple decorators can be combined flexibly; deep inheritance hierarchies become rigid and hard to extend. • Decorator keeps the original class unmodified, avoiding subclass proliferation for every feature combination. • Both preserve a common interface, but Decorator does it through composition rather than an "is-a" relationship.

Example: Instead of creating subclasses like EspressoWithMilk and EspressoWithMilkAndSugar for every combination of add-ons, a Decorator lets you wrap a plain Espresso object with a MilkDecorator and a SugarDecorator only when needed, on only the instances that need them.

Interview Tip: A concise interview answer is:

"Decorator adds behavior to specific object instances at runtime through composition, while inheritance adds behavior to an entire class at compile time. Decorator avoids the rigid, exploding class hierarchies you get when you try to cover every feature combination with subclasses."