Favor composition over inheritance is one of the popular
object-oriented design principles, which helps to create flexible
and maintainable code in Java and other object-oriented languages.
On composition, a class, which desire to use the functionality of
an existing class, doesn't inherit, instead, it holds a reference
of that class in a member variable, that’s why the name
composition. Inheritance and composition relationships are also
referred to as IS-A and HAS-A relationships.
- In OOP, the IS-A relationship is completely inheritance. This
means, that the child class is a type of parent class. For example,
an apple is a fruit. So you will extend fruit to get an apple.
- On the other hand, composition means creating instances that
have references to other objects. For example, a room has a table.
So you will create a classroom and then in that class create an
instance of a type table.
Composition becomes preferable for a number of
reasons:
- Though both Composition and Inheritance allows you to reuse
code, one of the disadvantages of Inheritance is that it breaks
encapsulation. If subclass is depending on superclass behavior for
its operation, it suddenly becomes fragile. When behavior of super
class changes, functionality in sub class may get broken, without
any change on its part. If you have used
Composition in favor of Inheritance you won't
face this problem and your class would have been more robust
because you are not relying on super class behavior any more.
- Composition offers better test-ability of a
class than Inheritance. If one class is composed of another class,
you can easily create Mock Object representing composed class for
sake of testing. Inheritance doesn't provide this luxury. In order
to test derived class, you must need its super class.
- Composition allows you to delay the creation
of components until they are needed, or to never create them at all
if they are not needed. Perhaps your
Car
is driving in
the day, and the lights aren’t needed, so they never even need to
be created.
- It is more natural to build business-domain classes out of
various components than trying to find commonality between them and
creating a family tree. For example, an accelerator pedal and a
steering wheel share very few common traits, yet both are vital
components in a car. What they can do and how they can be used to
benefit the car is easily defined. Composition also provides a more
stable business domain in the long term as it is less prone to the
quirks of the family members. In other words, it is better to
compose what an object can do (HAS-A) than extend what it
is (IS-A).
Prefer composition over inheritance
and you’ll have more flexible, extensible, and testable
code.