Card 06/ 08
Composition vs Inheritance
extends gets the behaviour in one word, and also publishes every method of the parent on your class.
Reusing a class by inheritance (extends) makes your class a kind of it, with every public method it has. Reusing it by composition means holding one in a private field and calling it, so your class exposes only the methods you choose to write.
A class needs what another class already does. A list that counts what is added to it, first by extending ArrayList, then by holding one:
class CountingList extends ArrayList<String> {
int added = 0;
@Override public boolean add(String s) { added++; return super.add(s); }
}class CountingList {
private final List<String> items = new ArrayList<>();
private int added = 0;
void add(String s) { added++; items.add(s); }
int added() { return added; }
}| Compared on | Inheritance, with extends | Composition, with a field |
|---|---|---|
| Relationship | This is a that | This has a that |
| Callers can use | Every public method of the parent | Only what you chose to expose |
| Breaks when | The parent changes how its methods call each other | The parent changes its behaviour |
| Swapping the implementation | Not possible: the parent is fixed | Change one field's type |
The decision rule. Ask whether every method of the parent should be callable on your object, and whether your object could sensibly be handed to code expecting the parent. Two yeses mean inheritance. Anything less means a field.
The extends ArrayList listing shows why this is more than tidiness. A subclass depends on how the parent's methods call each other, which is an implementation detail the parent is free to change in a patch release.
← → move through sections and cards