← Back to list

12.Composition Over Inheritance

Inheritance

Aly Route · 2026-06-20 18:49 · 0 claps · 1.3 min read
#composition #inheritance #dart
Open on Medium ↗
Wiki topics: VIS · Visual & Graphic Design

12.Composition Over Inheritance

Inheritance

Inheritance is the design technique in object-oriented programming to implement is-a relationship between objects.

Inheritance looks clean at first — share behaviour by extending a parent class. But it creates tight coupling that breaks badly as requirements grow.

// Seems fine at first...
class Animal {
  breathe() => print('breathing');
  eat()     => print('eating');
}

class Dog extends Animal {
  bark() => print('woof');
  run()  => print('running');
}

class Cat extends Animal {
  meow()  => print('meow');
  climb() => print('climbing');
}

But if we want to create a RobotDog class:-

  • Extending Dog forces RobotDog to inherit breathe() and eat() — things robots don’t do.
  • Dart has no multiple inheritance — you can’t extend both Dog and Robot.

A RobotDog IS-A Dog ==> Must take everything from parent. No choice.

In general Adding a new ability later means changing the parent — potentially breaking every subclass.

Composition

Composition is the design technique in object-oriented programming to implement has-a relationship between objects. It is achieved by using instance variables of other objects.

So instead of asking “what IS this thing?” (inheritance), ask “what can this thing DO?” (composition). Behaviours become small, independent objects that get plugged in.

// Abilities as small, focused classes
class Breather {
  breathe() => print('breathing');
}

class Barker {
  bark() => print('woof');
}

class Runner {
  run() => print('running');
}

// Real dog: breathes, barks, runs
class Dog {
  final _breather = Breather();
  final _barker   = Barker();
  final _runner   = Runner();

  breathe() => _breather.breathe();
  bark()    => _barker.bark();
  run()     => _runner.run();
}

// Robot dog: barks and runs — no breathing
class RobotDog {
  final _barker = Barker();
  final _runner = Runner();

  bark() => _barker.bark();
  run()  => _runner.run();
}

/*
- Barker can be updated without touching Dog or RobotDog.
- Adding a Swimmer ability to Dog later is trivial - no base class changes.
- No unwanted inherited methods to override or throw away.
*/

A RobotDog HAS-A Barker, HAS-A RunnerPick ==> exactly what you need.

Test Your Knowledge


메타데이터
post_id
d59229e7d9fd
slug
12-composition-over-inheritance-d59229e7d9fd
url
https://medium.com/@aly.route/12-composition-over-inheritance-d59229e7d9fd
canonical_url
https://medium.com/@aly.route/12-composition-over-inheritance-d59229e7d9fd
author_url
https://medium.com/@aly.route
status
ok
fetched_at
2026-07-17 14:41:54