Composition, inheritance, and delegation

Objects can contain other objects in their instance variables; this is known as object composition. For example, an object in the Employee class might contain (either directly or through a pointer) an object in the Address class, in addition to its own instance variables like first name and position". Object composition is used to represent has-a relationships: every employee has an address, so every Employee object has access to a place to store an Address object (either directly embedded within itself, or at a separate location addressed via a pointer).

Languages that support classes almost always support inheritance. This allows classes to be arranged in a hierarchy that represents is-a-type-of relationships. For example, class Employee might inherit from class Person. All the data and methods available to the parent class also appear in the child class with the same names. For example, class Person might define variables first name and last name with method make_full_name(). These will also be available in class Employee, which might add the variables position and salary. This technique allows easy reuse of the same procedures and data definitions, in addition to potentially mirroring real world relationships in an intuitive way. Rather than utilizing database tables and programming subroutines, the developer utilizes objects the user may be more familiar with: objects from their application domain.

Abstract classes cannot be instantiated into objects; they exist only for the purpose of inheritance into other concrete classes which can be instantiated. In Java, the final keyword can be used to prevent a class from being subclassed. The doctrine of composition over inheritance advocates implementing has-a relationships using composition instead of inheritance. For example, instead of inheriting from class Person, class Employee could give each Employee object an internal Person object, which it then has the opportunity to hide from external code even if class Person has many public attributes or methods. Some languages, like Go do not support inheritance at all. The open/closed principle advocates that classes and functions should be open for extension, but closed for modification. Delegation is another language feature that can be used as an alternative to inheritance.