The broken inheritance version, for comparison
The bug lives in the gap between HashSet's public API and its private implementation.
Composition means building a class by holding other objects in fields and delegating work to them (has-a), instead of inheriting from them (is-a). It avoids the fragile base class problem and lets behaviour change at run time, so prefer it unless the relationship is a true, stable is-a.
Change the code and press Run (Ctrl+Enter). Try to predict the output first, then break it on purpose and read the error. Your edits are saved and match the lesson page.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a Car that has an Engine interface field with PetrolEngine and ElectricEngine implementations. car.start() delegates to the engine. Swap the engine at run time.
Write a decorator UpperCaseWriter around an interface Writer { String write(String s); } and stack two decorators: one upper-cases, one adds !.
Rewrite class Stack2 extends ArrayList<Integer> as a class that composes an ArrayDeque<Integer> and exposes only push, pop, peek and isEmpty.
Explain it without notes
What is the difference between composition and inheritance? Give an example of each.
Explain the fragile base class problem using the counting HashSet example.
How does composition enable changing behaviour at run time?
When is inheritance the right choice?
Expected output
expected 3, got 6