Module 4 Lesson 8: Composition vs. Inheritance
Choosing the right way to build complex systems. Learn the 'is-a' vs. 'has-a' rule and why Composition is often better than Inheritance.
Module 4 Lesson 8: Composition vs. Inheritance
Inheritance is great for sharing code between a "Type" and its "Category" (A Dog is an Animal). But sometimes, using inheritance makes your code too tangled and rigid. What if an object doesn't inherit traits but simply uses other objects? This is called Composition.
Lesson Overview
In this lesson, we will cover:
- The "is-a" vs. "has-a" Rule: The ultimate design test.
- How Composition Works: Objects as attributes.
- Pros and Cons: When to use which.
- Practical Example: Building a Computer.
1. The Golden Rule
Before you write class B(A):, ask yourself:
- Inheritance (is-a): Is a Dog a kind of Animal? Yes! → Use Inheritance.
- Composition (has-a): Does a Computer have a kind of CPU? Yes! Is a Computer a kind of CPU? No! → Use Composition.
2. How Composition Works
In composition, you create an object and then pass it as an argument into another object’s constructor.
class Engine:
def start(self): print("Engine starting...")
class Car:
def __init__(self, brand):
self.brand = brand
self.engine = Engine() # The Car HAS AN Engine (Composition)
def drive(self):
self.engine.start()
print(f"The {self.brand} is moving!")
my_car = Car("Toyota")
my_car.drive()
3. Why Composition is Often Better
- Flexibility: You can swap out a
GasEnginefor anElectricEngineeasily. With inheritance, you'd have to create two entirely different Car classes (GasCarandElectricCar). - Decoupling: Parts can be changed or tested separately without breaking the whole system.
- No "Deep Hierarchies": You won't end up with a confusing
Vehicle -> LandVehicle -> WheeledVehicle -> Car -> SportsCarchain.
4. When to Use Each
- Inheritance: Use it when class
Breally is a specialized version of classA, and they share almost all behavior. - Composition: Use it when you are building a complex object out of smaller, independent parts.
Practice Exercise: The Robot Builder
Create a file named robot.py.
- Define a class
Armwith a methodgrasp(). - Define a class
Legwith a methodstep(). - Define a class
Robot. - In the
Robot's__init__, create an instance ofArmand an instance ofLeg. - Add a method
move_and_pick()toRobotthat calls the leg'sstep()and then the arm'sgrasp().
Quick Knowledge Check
- What is the "is-a" vs. "has-a" rule?
- In a "Bank" application, would a
Customerinherit from aBankor would aBankuse composition for itsCustomer? - Give one advantage of Composition over Inheritance.
- If a class
Birdinherits fromAnimal, what kind of relationship is that?
Key Takeaways
- Inheritance models relationship ("is-a").
- Composition models structural components ("has-a").
- Composition leads to more flexible and easier-to-change code.
- The best software usually uses a mix of both!
What’s Next?
Our methods so far always need an instance (my_car.drive()). But what if a method belongs to the Class itself (like Car.get_count())? In Lesson 9, we’ll look at Class and Static Methods!