Composition Over Inheritance
   HOME

TheInfoList



OR:

Composition over inheritance (or composite reuse principle) in
object-oriented programming Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code. The data is in the form of fields (often known as attributes or ''properties''), and the code is in the form of pr ...
(OOP) is the principle that classes should achieve polymorphic behavior and
code reuse In software development (and computer programming in general), code reuse, also called software reuse, is the use of existing software, or software knowledge, to build new software, following the reusability principles. Code reuse may be achiev ...
by their
composition Composition or Compositions may refer to: Arts and literature *Composition (dance), practice and teaching of choreography *Composition (language), in literature and rhetoric, producing a work in spoken tradition and written discourse, to include v ...
(by containing instances of other classes that implement the desired functionality) rather than
inheritance Inheritance is the practice of receiving private property, Title (property), titles, debts, entitlements, Privilege (law), privileges, rights, and Law of obligations, obligations upon the death of an individual. The rules of inheritance differ ...
from a base or parent class. This is an often-stated principle of OOP, such as in the influential book ''
Design Patterns ''Design Patterns: Elements of Reusable Object-Oriented Software'' (1994) is a software engineering book describing software design patterns. The book was written by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, with a foreword ...
'' (1994).


Basics

An implementation of composition over inheritance typically begins with the creation of various
interfaces Interface or interfacing may refer to: Academic journals * Interface (journal), ''Interface'' (journal), by the Electrochemical Society * ''Interface, Journal of Applied Linguistics'', now merged with ''ITL International Journal of Applied Lin ...
representing the behaviors that the system must exhibit. Interfaces can facilitate polymorphic behavior. Classes implementing the identified interfaces are built and added to business domain classes as needed. Thus, system behaviors are realized without inheritance. In fact, business domain classes may all be base classes without any inheritance at all. Alternative implementation of system behaviors is accomplished by providing another class that implements the desired behavior interface. A class that contains a reference to an interface can support implementations of the interface—a choice that can be delayed until runtime.


Example


Inheritance

An example in
C++ C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
follows: class Object ; class Visible : public Object ; class Solid : public Object ; class Movable : public Object ; Then, suppose we also have these concrete classes: * class - which is , and * class - which is and , but not * class - which is and , but not * class - which is , but neither nor Note that multiple inheritance is dangerous if not implemented carefully because it can lead to the
diamond problem Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit features from more than one parent object or parent class. It is distinct from single inheritance, where an object or ...
. One solution to this is to create classes such as , , , etc. for every needed combination; however, this leads to a large amount of repetitive code. C++ uses
virtual inheritance Virtual inheritance is a C++ technique that ensures only one copy of a base classs member variables are inherited by grandchild derived classes. Without virtual inheritance, if two classes B and C inherit from a class A, and a class D inherits fr ...
to solve the diamond problem of multiple inheritance.


Composition and interfaces

The C++ examples in this section demonstrate the principle of using composition and interfaces to achieve code reuse and polymorphism. Due to the C++ language not having a dedicated keyword to declare interfaces, the following C++ example uses inheritance from a pure
abstract base class In object-oriented programming, a class is an extensible program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods). In many languages, the class n ...
. For most purposes, this is functionally equivalent to the interfaces provided in other languages, such as Java and C#. Introduce an abstract class named , with the subclasses and , which provides a means of drawing an object: class VisibilityDelegate ; class NotVisible : public VisibilityDelegate ; class Visible : public VisibilityDelegate ; Introduce an abstract class named , with the subclasses and , which provides a means of moving an object: class UpdateDelegate ; class NotMovable : public UpdateDelegate ; class Movable : public UpdateDelegate ; Introduce an abstract class named , with the subclasses and , which provides a means of colliding with an object: class CollisionDelegate ; class NotSolid : public CollisionDelegate ; class Solid : public CollisionDelegate ; Finally, introduce a class named with members to control its visibility (using a ), movability (using an ), and solidity (using a ). This class has methods which delegate to its members, e.g. simply calls a method on the : class Object ; Then, concrete classes would look like: class Player : public Object ; class Smoke : public Object ;


Benefits

To favor composition over inheritance is a design principle that gives the design higher flexibility. 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 In database design, object-oriented programming and design (see object oriented program architecture), has-a (has_a or has a) is a composition relationship where one object (often called the constituted object, or part/constituent/member object) ...
'') than extend what it is (''
is-a In knowledge representation, object-oriented programming and design (see object-oriented program architecture), is-a (is_a or is a) is a subsumption relationship between abstractions (e.g. types, classes), wherein one class ''A'' is a subclass ...
''). Initial design is simplified by identifying system object behaviors in separate interfaces instead of creating a hierarchical relationship to distribute behaviors among business-domain classes via inheritance. This approach more easily accommodates future requirements changes that would otherwise require a complete restructuring of business-domain classes in the inheritance model. Additionally, it avoids problems often associated with relatively minor changes to an inheritance-based model that includes several generations of classes. Composition relation is more flexible as it may be changed on runtime, while sub-typing relations are static and need recompilation in many languages. Some languages, notably Go and
Rust Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH ...
, use type composition exclusively.


Drawbacks

One common drawback of using composition instead of inheritance is that methods being provided by individual components may have to be implemented in the derived type, even if they are only forwarding methods (this is true in most programming languages, but not all; see ). In contrast, inheritance does not require all of the base class's methods to be re-implemented within the derived class. Rather, the derived class only needs to implement (override) the methods having different behavior than the base class methods. This can require significantly less programming effort if the base class contains many methods providing default behavior and only a few of them need to be overridden within the derived class. For example, in the C# code below, the variables and methods of the base class are inherited by the and derived subclasses. Only the method needs to be implemented (specialized) by each derived subclass. The other methods are implemented by the base class itself, and are shared by all of its derived subclasses; they do not need to be re-implemented (overridden) or even mentioned in the subclass definitions. // Base class public abstract class Employee // Derived subclass public class HourlyEmployee : Employee // Derived subclass public class SalariedEmployee : Employee


Avoiding drawbacks

This drawback can be avoided by using traits,
mixin In object-oriented programming languages, a mixin (or mix-in) is a class that contains methods for use by other classes without having to be the parent class of those other classes. How those other classes gain access to the mixin's methods depend ...
s, (type)
embedding In mathematics, an embedding (or imbedding) is one instance of some mathematical structure contained within another instance, such as a group that is a subgroup. When some object X is said to be embedded in another object Y, the embedding is gi ...
, or
protocol Protocol may refer to: Sociology and politics * Protocol (politics), a formal agreement between nation states * Protocol (diplomacy), the etiquette of diplomacy and affairs of state * Etiquette, a code of personal behavior Science and technology ...
extensions. Some languages provide specific means to mitigate this: * C# provides default interface methods since version 8.0 which allows to define body to interface member. * D provides an explicit "alias this" declaration within a type can forward into it every method and member of another contained type. *
Dart Dart or DART may refer to: * Dart, the equipment in the game of darts Arts, entertainment and media * Dart (comics), an Image Comics superhero * Dart, a character from ''G.I. Joe'' * Dart, a ''Thomas & Friends'' railway engine character * Dar ...
provides mixins with default implementations that can be shared. * Go type embedding avoids the need for forwarding methods. *
Java Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's List ...
provides default interface methods since version 8. Project Lombok supports delegation using the annotation on the field, instead of copying and maintaining the names and types of all the methods from the delegated field. *
Julia Julia is usually a feminine given name. It is a Latinate feminine form of the name Julio and Julius. (For further details on etymology, see the Wiktionary entry "Julius".) The given name ''Julia'' had been in use throughout Late Antiquity (e.g. ...
macros can be used to generate forwarding methods. Several implementations exist such as Lazy.jl and TypedDelegation.jl. * Kotlin includes the delegation pattern in the language syntax. *
PHP PHP is a general-purpose scripting language geared toward web development. It was originally created by Danish-Canadian programmer Rasmus Lerdorf in 1993 and released in 1995. The PHP reference implementation is now produced by The PHP Group ...
supports traits. *
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (pro ...
supports use of the __getattr__ magic method to forward attribute requests. * Raku provides a trait to facilitate method forwarding. *
Rust Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH ...
provides traits with default implementations. * Scala (since version 3) provides an "export" clause to define aliases for selected members of an object. *
Swift Swift or SWIFT most commonly refers to: * SWIFT, an international organization facilitating transactions between banks ** SWIFT code * Swift (programming language) * Swift (bird), a family of birds It may also refer to: Organizations * SWIFT, ...
extensions can be used to define a default implementation of a protocol on the protocol itself, rather than within an individual type's implementation.


Empirical studies

A 2013 study of 93 open source Java programs (of varying size) found that:


See also

*
Delegation pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows object composition to achieve the same code reuse as inheritance. In delegation, an object handles a request by delegating to a second object (the ''de ...
*
Liskov substitution principle The Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called strong behavioral subtyping, that was initially introduced by Barbara Liskov in a 1988 conference keynote address titled ''Data abstraction and h ...
*
Object-oriented design Object-oriented design (OOD) is the process of planning a system of interacting objects for the purpose of solving a software problem. It is one approach to software design. Overview An object contains encapsulated data and procedures grouped t ...
*
Object composition In computer science, object composition and object aggregation are closely related ways to combine objects or data types into more complex ones. In conversation the distinction between composition and aggregation is often ignored. Common kind ...
*
Role-oriented programming Role-oriented programming as a form of computer programming aims at expressing things in terms that are analogous to human conceptual understanding of the world. This should make programs easier to understand and maintain. The main idea of rol ...
*
State pattern The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines. The state pattern can be interpreted as a strategy ...
*
Strategy pattern In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time ins ...


References

{{Reflist Component-based software engineering Software architecture Programming principles Articles with example C Sharp code