Categories
aggregation composition inheritance language-agnostic oop

Prefer composition over inheritance?

1869

Why prefer composition over inheritance? What trade-offs are there for each approach? When should you choose inheritance over composition?

2

  • 5

    See also which class design is better

    – maccullt

    Sep 10, 2008 at 2:22

  • 5

    in one sentence inheritance is public if you have a public method and you change it it changes the published api. if you have composition and the object composed has changed you don’t have to change your published api.

    Aug 26, 2015 at 11:00

526

Think of containment as a has a relationship. A car “has an” engine, a person “has a” name, etc.

Think of inheritance as an is a relationship. A car “is a” vehicle, a person “is a” mammal, etc.

I take no credit for this approach. I took it straight from the Second Edition of Code Complete by Steve McConnell, Section 6.3.

10

  • 126

    This is not always a perfect approach, it’s simply a good guideline. the Liskov Substitution Principle is much more accurate (fails less).

    – Bill K

    Sep 17, 2008 at 0:25

  • 45

    “My car has a vehicle.” If you consider that as a separate sentence, not in a programming context, that makes absolutely no sense. And that’s the whole point of this technique. If it sounds awkward, it is probably wrong.

    Aug 14, 2011 at 18:27


  • 48

    @Nick Sure, but “My Car has a VehicleBehavior” makes more sense (I guess your “Vehicle” class could be named “VehicleBehavior”). So you cannot base your decision on “has a” vs “is a” comparision, you have to use LSP, or you will make mistakes

    – Tristan

    Aug 26, 2011 at 11:53

  • 42

    Instead of “is a” think of “behaves like.” Inheritance is about inheriting behavior, not just semantics.

    – ybakos

    Mar 31, 2012 at 19:25

  • 11

    This doesn’t answer the question. The question is “why” not “what”.

    – Nick Bull

    Oct 20, 2017 at 10:57

255

If you understand the difference, it’s easier to explain.

Procedural Code

An example of this is PHP without the use of classes (particularly before PHP5). All logic is encoded in a set of functions. You may include other files containing helper functions and so on and conduct your business logic by passing data around in functions. This can be very hard to manage as the application grows. PHP5 tries to remedy this by offering more object oriented design.

Inheritance

This encourages the use of classes. Inheritance is one of the three tenets of OO design (inheritance, polymorphism, encapsulation).

class Person {
   String Title;
   String Name;
   Int Age
}

class Employee : Person {
   Int Salary;
   String Title;
}

This is inheritance at work. The Employee “is a” Person or inherits from Person. All inheritance relationships are “is-a” relationships. Employee also shadows the Title property from Person, meaning Employee.Title will return the Title for the Employee not the Person.

Composition

Composition is favoured over inheritance. To put it very simply you would have:

class Person {
   String Title;
   String Name;
   Int Age;

   public Person(String title, String name, String age) {
      this.Title = title;
      this.Name = name;
      this.Age = age;
   }

}

class Employee {
   Int Salary;
   private Person person;

   public Employee(Person p, Int salary) {
       this.person = p;
       this.Salary = salary;
   }
}

Person johnny = new Person ("Mr.", "John", 25);
Employee john = new Employee (johnny, 50000);

Composition is typically “has a” or “uses a” relationship. Here the Employee class has a Person. It does not inherit from Person but instead gets the Person object passed to it, which is why it “has a” Person.

Composition over Inheritance

Now say you want to create a Manager type so you end up with:

class Manager : Person, Employee {
   ...
}

This example will work fine, however, what if Person and Employee both declared Title? Should Manager.Title return “Manager of Operations” or “Mr.”? Under composition this ambiguity is better handled:

Class Manager {
   public string Title;
   public Manager(Person p, Employee e)
   {
      this.Title = e.Title;
   }
}

The Manager object is composed as an Employee and a Person. The Title behaviour is taken from employee. This explicit composition removes ambiguity among other things and you’ll encounter fewer bugs.

21

  • 7

    For inheritence: There is no ambiguity. You are implementing the Manager class based on requirements. So you would return “Manager of Operations” if thats what your requirements specified, else you would just use the base class’s implementation. Also you could make Person an abstract class and thereby make sure down-stream classes implement a Title property.

    – Raj Rao

    Nov 12, 2010 at 20:21


  • 87

    Its important to remember that one might say “Composition over inheritence” but that does not mean “Composition always over Inheritence”. “Is a” means inheritence and leads to code reuse. Employee is a Person (Employee does not have a person).

    – Raj Rao

    Nov 12, 2010 at 20:26

  • 45

    The example is confusing.Employee is a person, so it should use inheritance. You should not use composition for this example, because it is wrong relationship in domain model, even if technically you can declare it in the code.

    Jul 24, 2013 at 13:54


  • 25

    I disagree with this example. An Employee is-a Person, which is a textbook case of proper use of inheritance. I also think that the “issue” the redefinition of the Title field does not make sense. The fact that Employee.Title shadows Person.Title is a sign of poor programming. After all, are “Mr.” and “Manager of Operations” really referring to the same aspect of a person (lowercase)? I would rename Employee.Title, and thus be able to reference the Title and JobTitle attributes of an Employee, both of which make sense in real life. Furthermore, there is no reason for Manager (continued…)

    Nov 10, 2014 at 0:09

  • 17

    (… continued) to inherit from both Person and Employee — after all, Employee already inherits from Person. In more complex models, where a person might be a Manager and an Agent, it is true that multiple inheritance can be used (carefully!), but it would be preferable in many environments to have an abstract Role class from which Manager (contains Employees s/he manages) and Agent (contains Contracts, and other information) inherit. Then, an Employee is-a Person who has-multiple Roles. Thus, both composition and inheritance are used properly.

    Nov 10, 2014 at 0:13