# Composition

URL: https://softwaredictionary.org/terms/object-composition
Category: Programming Fundamentals
Last updated: 2026-10-06
In Turkish: Bileşim
Pronunciation: kom-puh-ZISH-un

In short: Composition builds an object out of other objects that it holds and delegates work to, modeling a has-a relationship instead of inheriting from a parent class.

## What is composition in programming?

Composition means building a class from other objects instead of extending a parent class. A `Car` doesn't inherit from `Engine`; it has an engine, kept in a field, and its `start()` method simply asks that engine to start. Passing work on to an object you hold like this is called delegation, and the relationship is described as has-a: a car has an engine, a page has a header, an order has line items.

Because the parts are ordinary objects, usually behind interfaces, they can be swapped. A car can get an electric engine instead of a petrol one when it is built, or even while the program runs, and a test can hand in a fake engine. The strategy, decorator and dependency injection patterns are all built on this idea. It is like building with LEGO bricks instead of carving a statue from one block: every part stays separate and replaceable.

"Favor object composition over class inheritance" is a principle from the 1994 book Design Patterns by the authors known as the Gang of Four. Inheritance ties a subclass to its parent's internals, so a change in the parent can break every child, and hierarchies multiply when features combine: `ElectricCar`, `HybridCar`, `SelfDrivingElectricCar`. Some languages lean on composition by design: Go has no class inheritance and embeds one struct in another instead, and Kotlin can delegate a whole interface to a field with the `by` keyword.

Composition is mostly weighed against inheritance, and the test is the relationship. Use inheritance when one type truly is a kind of another, as a `Dog` is an `Animal`, and composition when it has or uses something. Composition costs a little more code, since each delegating method has to be written, but the result is easier to change. The word has two other meanings as well: in UML diagrams, composition is a strong ownership where the parts live and die with the whole, and in functional programming, function composition chains functions so the output of one feeds the next.

## Key takeaways

- Composition builds an object from other objects that it holds and delegates to.
- It models a has-a relationship, while inheritance models an is-a relationship.
- Parts behind interfaces can be swapped, which keeps code flexible and easy to test.
- "Composition over inheritance" means reaching for composition first when reusing behavior.
- Go and Kotlin support it directly, through struct embedding and the `by` keyword.

## Example: A car that has an engine, instead of inheriting from one (TypeScript)

```typescript
interface Engine { start(): string; }

class PetrolEngine implements Engine { start() { return "vroom"; } }
class ElectricEngine implements Engine { start() { return "hum"; } }

// A Car HAS an engine and delegates to it, so there is no need for
// PetrolCar, ElectricCar and HybridCar subclasses
class Car {
  constructor(private engine: Engine) {}
  start() { return `Car starting: ${this.engine.start()}`; }
}

new Car(new ElectricEngine()).start(); // "Car starting: hum"
```

## Frequently asked questions

**What does "composition over inheritance" mean?**

It is a design guideline: to reuse behavior, prefer holding an object that provides it over extending a class that has it. Inheritance isn't forbidden; it is kept for true is-a relationships.

**What is the difference between composition and aggregation?**

Both are has-a relationships. In UML, composition means the whole owns its parts and they are destroyed with it, like a house and its rooms, while aggregation means the parts can exist on their own, like a team and its players. In everyday code, the word composition usually covers both.

**How does composition make testing easier?**

The parts usually arrive from outside, often through the constructor, so a test can pass in a stub or a fake, such as an in-memory database instead of the real one, without changing the class itself.

## Sources

- [Effective Go: Embedding](https://go.dev/doc/effective_go#embedding)
- [Kotlin documentation: Delegation](https://kotlinlang.org/docs/delegation.html)

---

Software Dictionary: https://softwaredictionary.org/ · https://softwaredictionary.org/llms.txt
