Skip to main content

Composition

In Turkish
Bileşim
Pronunciation
kom-puh-ZISH-un
Updated 3 min read

Share this page

Send the link, quote the definition with a link back, or show it as a card on your own site.

https://softwaredictionary.org/terms/object-composition

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"

Readers ask

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.

See also

Sources

Spotted a mistake or something missing on this page?Suggest an edit

More

Settings