Object composition

In computer science, object composition is a way to combine objects or data types into more complex ones. Compositions relate to, but are not the same as, data structures, and common ones are the tagged union, set, sequence, and various graph structures, as well as the object used in object-oriented programming.
Object composition refers to the logical or conceptual structure of the information, not the implementation or physical data structure used to represent it. For example, a sequence differs from a set because the order of the composed items matters for the former but not the latter. Data structures such as arrays, linked lists, hash tables, and many others can be used to implement either of them. Perhaps confusingly, some of the same terms are used for both data structures and composites. For example, "binary tree" can refer to either: as a data structure it is a means of accessing a linear sequence of items, and the actual positions of items in the tree are irrelevant. However, as an object composition, the positions are relevant, and changing them would change the meaning.


In programming, types can often be divided into composite and noncomposite types, and composition can be regarded as a relationship between types: an object of a composite type "has" objects of other types. When a composite object contains several sub-objects of the same type, they may be assigned to particular roles, often distinguished by names or numbers. For example, a Point object might contain 3 numbers, each representing distance along a different axis, such as 'x', 'y', and 'z'. The study of part-whole relationships in general, is mereology.
Composition must be distinguished from subtyping, which is the process of adding detail to a general data type to create a more specific data type. For instance, cars may be a specific type of vehicle: car is a vehicle. Subtyping doesn't describe a relationship between different objects, but instead, says that objects of a type are simultaneously objects of another type. The study of such relationships is ontology.
Composite objects may be represented in storage by co-locating the composed items, by co-locating references, or in many other ways. The items within a composite object may be referred to as attributes, fields, members, properties, or other names, and the resulting composition as composite type, storage record, structure, tuple, or a user-defined type . For details, see the aggregation section below.

UML notation

In UML, there are two ways of modeling composites: Composition and aggregation. Thus in UML, composition has a more narrow meaning than in ordinary language:
Composition is depicted as a filled diamond and a solid line.
Composition is a kind of association where the composite object has sole "responsibility for the existence and storage of the composed objects". The relationship between the composite and the component is a strong “has a” relationship, as the composite object takes ownership of the component. This means the composite is responsible for the creation and destruction of the component parts. An object may only be part of one composite. If the composite object is destroyed, all the component parts must be destroyed. The part has no life of itself and cannot be transferred to another object. Composition enforces encapsulation as the component parts usually are members of the composite object.
The more general form, aggregation, is depicted as an unfilled diamond and a solid line.
Aggregation is a kind of association that specifies a whole/part relationship between the aggregate and component part. This relationship between the aggregate and component is a weak "has-a" relationship, as the component may outlive the aggregate object. The component object may be accessed through other objects without going through the aggregate object. The aggregate object does not take part in the lifecycle of the component object, meaning the component object may outlive the aggregate object. The state of the component object still forms part of the aggregate object.
A C++ implementation could be something like this:

// Composition:
class Car ;

// Aggregation:
class Pond ;

Composite types in C

This is an example of composition in C.

struct Person

In this example, the primitive types int, enum and the composite array type char are combined to form the composite structure Person. Each Person structure then "has an" age, name, and an employment type.

Recursive composition

Objects can be composed recursively, and are then called recursive types. Examples includes various kinds of trees, DAGs, and graphs. Each node in a tree may be a branch or leaf; in other words, each node is a tree at the same time when it belongs to another tree.

Timeline of composition in various languages

calls a record a struct or structure; object-oriented languages such as Java, Smalltalk, and C++ often keep their records hidden inside objects ; languages in the ML family simply call them records. COBOL was the first widespread programming language to support records directly; ALGOL 68 got it from COBOL and Pascal got it, more or less indirectly, from ALGOL 68. Common Lisp provides structures and classes.
;1959 – COBOL

01 customer-record.
03 customer-number pic 9 comp.
03 customer-name.
05 given-names pic x.
05 initial-2 pic x.
05 surname pic x.
03 customer-address.
05 street.
07 street-name pic x.
09 house-number pic 999 comp.
05 city pic x.
05 country-code pic x.
05 postcode pic x.
03 amount-owing pic 9 comp.

;1960 – ALGOL 60
Arrays were the only composite data type in Algol 60.
;1964 – PL/I

dcl 1 newtypet based ;
2 fixed bin,
2 float,
2 r ptr;
allocate newtypet;

;1968 – ALGOL 68

int max = 99;
mode newtypet = struct ;
newtypet newarrayt =

For example, a linked list might be declared as:

mode node = union,
list = struct ;

For ALGOL 68 only the type name appears to the left of the equality, and most notably the construction is made – and can be read – from left to right without regard to priorities.
;1970 – Pascal

a = array of integer;
b = record
a, b, c: real;
i, j, k: integer;

;1972 – K&R C

  1. define max 99
struct newtypet newarrayt ;

;1977 – FORTRAN 77
Fortran 77 has arrays, but lacked any formal record/structure definitions. Typically compound structures were built up using EQUIVALENCE or COMMON statements:


;1983 – Ada

type Cust is
Name : Name_Type;
Addr : Addr_Type;
Phone : Phone_Type;
Owing : Integer range 1..999999;
end record;
Ada 95 brought OOP concepts through tagged types, Ada 2012 added support for substitution verification through class-wide contracts.
;1983 – C++

const int max = 99;
class newtypet ;

;1991 – Python

max = 99
class NewTypeT:
def __init__:
self.a = self.b = self.c = 0
self.i = self.j = self.k = 0.0
  1. Initialise an example array of this class.
newarrayt = NewTypeT for i in range] for j in range]

;1992 – FORTRAN 90
Arrays and strings were inherited from FORTRAN 77, and a new reserved word was introduced: type

type newtypet
double precision a, b, c
integer*2 i, j, k
  • No pointer type REF REAL R
end type
type t

FORTRAN 90 updated and included FORTRAN IV's concept called NAMELIST.

INTEGER :: jan = 1, feb = 2, mar = 3, apr = 4
NAMELIST / week / jan, feb, mar, apr

;1994 – ANSI Common Lisp
Common Lisp provides structures and the ANSI Common Lisp standard added CLOS classes.


For more details about composition in C/C++, see Composite type.


Aggregation differs from ordinary composition in that it does not imply ownership. In composition, when the owning object is destroyed, so are the contained objects. In aggregation, this is not necessarily true. For example, a university owns various departments, and each department has a number of professors. If the university closes, the departments will no longer exist, but the professors in those departments will continue to exist. Therefore, a University can be seen as a composition of departments, whereas departments have an aggregation of professors. In addition, a Professor could work in more than one department, but a department could not be part of more than one university.
Composition is usually implemented such that an object contains another object. For example, in C++:

class Professor; // Defined elsewhere
class Department ;
class University ;

In aggregation, the object may only contain a reference or pointer to the object.
Sometimes aggregation is referred to as composition when the distinction between ordinary composition and aggregation is unimportant.
The above code would transform into the following UML Class diagram:

Aggregation in COM

In Microsoft's Component Object Model, aggregation means that an object exports, as if it were their owner, one or several interfaces of another object it owns. Formally, this is more similar to composition or encapsulation than aggregation. However, instead of implementing the exported interfaces by calling the interfaces of the owned object, the interfaces of the owned object themselves are exported. The owned object is responsible for assuring that methods of those interfaces inherited from IUnknown actually invoke the corresponding methods of the owner. This is to guarantee that the reference count of the owner is correct and all interfaces of the owner are accessible through the exported interface, while no other interfaces of the owned object are accessible.


Composition that is used to store several instances of the composited data type is referred to as containment. Examples of such containers are arrays, associative arrays, binary trees, and linked lists.
In UML, containment is depicted with a multiplicity of 1 or 0..n, indicating that the data type is composed of an unknown number of instances of the composited data type.