Favoring composition over inheritance is a principle in software design that encourages using object composition (combining objects) rather than class inheritance to achieve code reuse and flexibility. While inheritance creates a tightly coupled hierarchy, composition allows for more modular and adaptable systems.
Consider a class hierarchy for shapes:
class Shape { void draw() { // Default draw implementation } } class Circle extends Shape { @Override void draw() { System.out.println("Drawing a circle"); } } class Square extends Shape { @Override void draw() { System.out.println("Drawing a square"); } }
Using inheritance, you create a hierarchy that is rigid and harder to modify. Instead, use composition:
interface DrawBehavior { void draw(); } class CircleBehavior implements DrawBehavior { public void draw() { System.out.println("Drawing a circle"); } } class SquareBehavior implements DrawBehavior { public void draw() { System.out.println("Drawing a square"); } } class Shape { private DrawBehavior drawBehavior; Shape(DrawBehavior drawBehavior) { this.drawBehavior = drawBehavior; } void performDraw() { drawBehavior.draw(); } }
This approach makes it easier to add new behaviors or modify existing ones without affecting other parts of the system.
Favoring composition over inheritance leads to more flexible, maintainable, and modular code. It allows you to reuse and extend behaviors dynamically, avoiding the pitfalls of rigid inheritance hierarchies.