No history yet

Composition vs Inheritance

What an Object Is vs. What It Does

In object-oriented programming, there are two primary ways to structure relationships between different types of objects: inheritance and composition. For a long time, inheritance was the go-to model. It's based on an "is-a" relationship. For example, an Orc is an Enemy, and a Goblin is an Enemy. This creates a neat family tree, or hierarchy.

Lesson image

In this model, you might create a base Enemy class with shared logic, like health and attack(). The Orc and Goblin classes would then inherit this logic automatically. This seems efficient at first. You write the code once, and everyone in the family gets it. But this approach can become rigid and hard to manage as your game grows more complex.

What if you want to create a friendly shopkeeper who can be attacked but can't fight back? Does he inherit from Enemy? What about a destructible barrel that has health but doesn't move or attack? This is where the inheritance model starts to break down. You end up with strange, deep hierarchies and can run into the Fragile Base Class problem, where a small change in a parent class unexpectedly breaks its many children.

A More Flexible Approach

Composition offers a different way of thinking. Instead of focusing on what an object is, it focuses on what an object has. This is a "has-a" relationship. An Orc isn't just an Enemy; it's an object that has Health, has an Attack behavior, and has Movement logic. A destructible barrel has Health. Your player character also has Health and has Movement logic.

Notice the pattern? Instead of locking functionality into a rigid family tree, we create small, reusable scripts—or components—that handle one specific job. Health, movement, attacking, and interacting are all separate building blocks. You can then attach these blocks to any game object to give it that capability. This is the core philosophy behind Unity's architecture.

This "mix-and-match" approach is incredibly powerful. You can create new types of objects just by combining existing components in novel ways. It also prevents code duplication without forcing unrelated objects into the same family tree. The Player and the Orc don't need to be related, they just both happen to use the same Health and Movement components. This makes your code more flexible, easier to test, and simpler to reason about. While inheritance still allows for powerful polymorphism where you can treat different objects in the same way, modern game development, especially in Unity, heavily favors composition.

Favor object composition over class inheritance

By building your game objects from small, single-responsibility components, you create a system that is robust and easy to change. Need a new enemy type that teleports instead of walks? Just swap out the Movement component for a Teleport component. The Health and Attack logic can stay exactly the same. This is the power of thinking in terms of what an object does rather than what it is.

Time to check your understanding.

Quiz Questions 1/5

Which of the following phrases best describes the core relationships defined by inheritance and composition, respectively?

Quiz Questions 2/5

You are designing a game and need to create a Player, an Orc, and a DestructibleBarrel. All three can be damaged and have health. Which design approach is generally more flexible and favored in modern game engines like Unity?

Embracing composition is a fundamental shift that aligns perfectly with how Unity is designed, leading to cleaner, more scalable game projects.