SlideShare a Scribd company logo
Favor Composition over
Inheritance
Kochih Wu
Based on Item 16 from Effective Java, 2nd ed.
Use case
Count how many elements have been added to a HashSet
InstrumentedHashSet implementation
public class InstrumentedHashSet<E> extends HashSet<E> {
// The number of attempted element insertions
private int addCount = 0;
public InstrumentedHashSet() { }
public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); }
@Override public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
Let’s run it
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
assertEquals(3, s.getAddCount());
Output
java.lang.AssertionError:
Expected :3
Actual :6
Issues with inheritance
● Inheritance violates encapsulation
○ Internally HashSet.addAll() calls add()
● Reimplement addAll() using add(), instead of calling super.addAll()?
○ Not reusing code
○ Not always possible without access to private fields
○ New methods can be added to the superclass
Take 2 using composition
// Wrapper class - uses composition in place of inheritance
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
@Override public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
Forwarding class
public class ForwardingSet<E> implements Set<E> {
private final Set<E> s;
public ForwardingSet(Set<E> s) { this.s = s; }
public void clear() { s.clear(); }
public boolean contains(Object o) { return s.contains(o); }
public boolean isEmpty() { return s.isEmpty(); }
public int size() { return s.size(); }
public Iterator<E> iterator() { return s.iterator(); }
public boolean add(E e) { return s.add(e); }
public boolean remove(Object o) { return s.remove(o); }
public boolean containsAll(Collection<?> c) { return s.containsAll(c); }
public boolean addAll(Collection<? extends E> c) { return s.addAll(c); }
public boolean removeAll(Collection<?> c) { return s.removeAll(c); }
public boolean retainAll(Collection<?> c) { return s.retainAll(c); }
public Object[] toArray() { return s.toArray(); }
public <T> T[] toArray(T[] a) { return s.toArray(a); }
@Override public boolean equals(Object o) { return s.equals(o); }
@Override public int hashCode() { return s.hashCode(); }
@Override public String toString() { return s.toString(); }
}
Let’s run it again
Set<String> s = new InstrumentedHashSet<String>(new HashSet<String>(capacity));
s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));
assertEquals(3, s.getAddCount());
Composition pros & cons
● The wrapper class can be used to instrument any Set implementation
○ Also known as the Decorator pattern
● Not suitable for callback frameworks
Takeaway
● Inheritance should only be used to represent an “is-a” relationship
● Inheritance propagates flaws in the API
● Law of Demeter (or principle of least knowledge)
Discussion

More Related Content

DOCX
2 a networkflow
PDF
Quick 入門 | iOS RDD テストフレームワーク for Swift/Objective-C
PDF
Apache Collection utils
TXT
Addthis widget
DOC
Caching a page
DOCX
C++ assignment
2 a networkflow
Quick 入門 | iOS RDD テストフレームワーク for Swift/Objective-C
Apache Collection utils
Addthis widget
Caching a page
C++ assignment

What's hot (19)

PPTX
Lessons learned from functional programming
RTF
PDF
Goの時刻に関するテスト
DOCX
Document
PDF
1 borland c++ 5.02 by aramse
PPTX
Image magick++
DOCX
Basic Programs of C++
PDF
JavaScript Event Loop
PDF
2016 gunma.web games-and-asm.js
PDF
Real world scala
PPTX
JavaScript Event Loop
PPT
Pig TPC-H Benchmark and Performance Tuning
PDF
20151224-games
PDF
Watch out: Observables are here to stay
PPTX
C- Programs - Harsh
PDF
AJUG April 2011 Cascading example
PDF
Rntb20200805
 
PDF
Concept of Stream API Java 1.8
KEY
関数ぷログラミング紹介
Lessons learned from functional programming
Goの時刻に関するテスト
Document
1 borland c++ 5.02 by aramse
Image magick++
Basic Programs of C++
JavaScript Event Loop
2016 gunma.web games-and-asm.js
Real world scala
JavaScript Event Loop
Pig TPC-H Benchmark and Performance Tuning
20151224-games
Watch out: Observables are here to stay
C- Programs - Harsh
AJUG April 2011 Cascading example
Rntb20200805
 
Concept of Stream API Java 1.8
関数ぷログラミング紹介
Ad

Similar to Favor composition over inheritance (20)

PDF
Project Manifold (Forwarding and Delegation)
PPSX
Java.lang.object
PDF
Java 8 - Nuts and Bold - SFEIR Benelux
PDF
C h 04 oop_inheritance
PPT
Java for the Impatient, Java Constructors, Scope, Wrappers, Inheritance, and ...
PPTX
Java Polymorphism Part 2
PPTX
Collections
PPTX
20.2 Java inheritance
PDF
Google guava
PDF
E6
PPT
7 inheritance
PPTX
Oop inheritance chapter 3
PPT
Inheritance and-polymorphism
PDF
Inheritance
PPTX
Lab 02bbnbnbbbb,nmn,mn,nnnklnlnlnknln.pptx
KEY
Ej Chpt#4 Final
PPTX
Chapter 04 Object Oriented programming .pptx
PPT
InheritanceAndPolymorphismprein Java.ppt
PPT
06 InheritanceAndPolymorphism.ppt
Project Manifold (Forwarding and Delegation)
Java.lang.object
Java 8 - Nuts and Bold - SFEIR Benelux
C h 04 oop_inheritance
Java for the Impatient, Java Constructors, Scope, Wrappers, Inheritance, and ...
Java Polymorphism Part 2
Collections
20.2 Java inheritance
Google guava
E6
7 inheritance
Oop inheritance chapter 3
Inheritance and-polymorphism
Inheritance
Lab 02bbnbnbbbb,nmn,mn,nnnklnlnlnknln.pptx
Ej Chpt#4 Final
Chapter 04 Object Oriented programming .pptx
InheritanceAndPolymorphismprein Java.ppt
06 InheritanceAndPolymorphism.ppt
Ad

Recently uploaded (20)

PPTX
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Website Design Services for Small Businesses.pdf
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Oracle Fusion HCM Cloud Demo for Beginners
PDF
iTop VPN Free 5.6.0.5262 Crack latest version 2025
PPTX
Computer Software and OS of computer science of grade 11.pptx
PPTX
assetexplorer- product-overview - presentation
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
CapCut Video Editor 6.8.1 Crack for PC Latest Download (Fully Activated) 2025
PDF
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PDF
iTop VPN Crack Latest Version Full Key 2025
PPTX
Operating system designcfffgfgggggggvggggggggg
PPTX
Monitoring Stack: Grafana, Loki & Promtail
PDF
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free
AMADEUS TRAVEL AGENT SOFTWARE | AMADEUS TICKETING SYSTEM
Design an Analysis of Algorithms I-SECS-1021-03
Website Design Services for Small Businesses.pdf
Complete Guide to Website Development in Malaysia for SMEs
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Oracle Fusion HCM Cloud Demo for Beginners
iTop VPN Free 5.6.0.5262 Crack latest version 2025
Computer Software and OS of computer science of grade 11.pptx
assetexplorer- product-overview - presentation
Design an Analysis of Algorithms II-SECS-1021-03
17 Powerful Integrations Your Next-Gen MLM Software Needs
Reimagine Home Health with the Power of Agentic AI​
CapCut Video Editor 6.8.1 Crack for PC Latest Download (Fully Activated) 2025
iTop VPN 6.5.0 Crack + License Key 2025 (Premium Version)
CHAPTER 2 - PM Management and IT Context
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
iTop VPN Crack Latest Version Full Key 2025
Operating system designcfffgfgggggggvggggggggg
Monitoring Stack: Grafana, Loki & Promtail
Tally Prime Crack Download New Version 5.1 [2025] (License Key Free

Favor composition over inheritance

  • 1. Favor Composition over Inheritance Kochih Wu Based on Item 16 from Effective Java, 2nd ed.
  • 2. Use case Count how many elements have been added to a HashSet
  • 3. InstrumentedHashSet implementation public class InstrumentedHashSet<E> extends HashSet<E> { // The number of attempted element insertions private int addCount = 0; public InstrumentedHashSet() { } public InstrumentedHashSet(int initCap, float loadFactor) { super(initCap, loadFactor); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } }
  • 4. Let’s run it InstrumentedHashSet<String> s = new InstrumentedHashSet<String>(); s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); assertEquals(3, s.getAddCount());
  • 6. Issues with inheritance ● Inheritance violates encapsulation ○ Internally HashSet.addAll() calls add() ● Reimplement addAll() using add(), instead of calling super.addAll()? ○ Not reusing code ○ Not always possible without access to private fields ○ New methods can be added to the superclass
  • 7. Take 2 using composition // Wrapper class - uses composition in place of inheritance public class InstrumentedSet<E> extends ForwardingSet<E> { private int addCount = 0; public InstrumentedSet(Set<E> s) { super(s); } @Override public boolean add(E e) { addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return super.addAll(c); } public int getAddCount() { return addCount; } }
  • 8. Forwarding class public class ForwardingSet<E> implements Set<E> { private final Set<E> s; public ForwardingSet(Set<E> s) { this.s = s; } public void clear() { s.clear(); } public boolean contains(Object o) { return s.contains(o); } public boolean isEmpty() { return s.isEmpty(); } public int size() { return s.size(); } public Iterator<E> iterator() { return s.iterator(); } public boolean add(E e) { return s.add(e); } public boolean remove(Object o) { return s.remove(o); } public boolean containsAll(Collection<?> c) { return s.containsAll(c); } public boolean addAll(Collection<? extends E> c) { return s.addAll(c); } public boolean removeAll(Collection<?> c) { return s.removeAll(c); } public boolean retainAll(Collection<?> c) { return s.retainAll(c); } public Object[] toArray() { return s.toArray(); } public <T> T[] toArray(T[] a) { return s.toArray(a); } @Override public boolean equals(Object o) { return s.equals(o); } @Override public int hashCode() { return s.hashCode(); } @Override public String toString() { return s.toString(); } }
  • 9. Let’s run it again Set<String> s = new InstrumentedHashSet<String>(new HashSet<String>(capacity)); s.addAll(Arrays.asList("Snap", "Crackle", "Pop")); assertEquals(3, s.getAddCount());
  • 10. Composition pros & cons ● The wrapper class can be used to instrument any Set implementation ○ Also known as the Decorator pattern ● Not suitable for callback frameworks
  • 11. Takeaway ● Inheritance should only be used to represent an “is-a” relationship ● Inheritance propagates flaws in the API ● Law of Demeter (or principle of least knowledge)