🔹 Composition vs. Inheritance in OOP

**Composition** and **Inheritance** are two fundamental techniques for **code reuse** in Object-Oriented Programming (OOP). Choosing between them depends on the relationship between objects and how flexible you want your code to be.

📌 What is Inheritance?

**Inheritance** is a mechanism where one class (**child/subclass**) derives properties and behaviors from another class (**parent/superclass**). It establishes an **"is-a" relationship**.

✅ **Example:** A **Car** "is a" type of **Vehicle**.


            class Vehicle {
                String brand = "Toyota";
            
                void honk() {
                    System.out.println("Honk! Honk!");
                }
            }
            
            class Car extends Vehicle {
                int speed = 100;
            }
            
            public class Main {
                public static void main(String[] args) {
                    Car myCar = new Car();
                    System.out.println(myCar.brand);  // ✅ Inherited from Vehicle
                    myCar.honk();  // ✅ Inherited behavior
                }
            }
                

📌 What is Composition?

**Composition** is a technique where a class **contains** an instance of another class instead of inheriting from it. It establishes a **"has-a" relationship**.

✅ **Example:** A **Car** "has an" **Engine**.


            class Engine {
                void start() {
                    System.out.println("Engine started...");
                }
            }
            
            class Car {
                private Engine engine = new Engine();  // Composition
            
                void startCar() {
                    engine.start();  // Using the engine object
                }
            }
            
            public class Main {
                public static void main(String[] args) {
                    Car myCar = new Car();
                    myCar.startCar();  // ✅ Delegates work to Engine
                }
            }
                

📌 Key Differences: Composition vs. Inheritance

Feature Inheritance Composition
Relationship Type "is-a" (Car **is a** Vehicle) "has-a" (Car **has an** Engine)
Code Reusability Directly reuses parent class methods Uses another class via an instance
Flexibility Less flexible (Tightly coupled) More flexible (Loosely coupled)
Extensibility Changes affect all subclasses Encapsulated; easy to modify
Encapsulation Weaker encapsulation Stronger encapsulation

📌 When to Use Composition vs. Inheritance?

  • ✅ **Use Inheritance** when there is a **clear "is-a" relationship** (e.g., Dog is an Animal).
  • ✅ **Use Composition** when objects **contain other objects** (e.g., Car has an Engine).
  • ✅ **Prefer Composition** when designing **flexible, loosely coupled systems**.

🎯 Summary

**Inheritance** provides direct access to a parent class, making it **easy to reuse** but **less flexible**. **Composition** promotes **modular and reusable** code by **delegating responsibilities** between objects.

🔗 Next Topics