<aside> 💡 상속은 코드를 재사용하는 강력한 수단이지만, 항상 최선은 아니다!

</aside>

public class InstrumentedHashSet<E> extends HashSet<E> {

		private int addCount = 0;

		public InstrumentedHashSet() {
		}

		public InstrumentedHashSet(final int initCap, final float loadFactor) {
				super(initCap, loadFactor);
		}

		@Override 
	  public boolean add(final E e) {
				addCount++;
				return super.add(e);
		}

		@Override 
		public boolean addAll(final Collection<? extends E> c) {
				addCount += c.size();
				return super.addAll(c);
		}

		public int getAddCount() {
				return addCount;
		}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(List.of("틱", "틱틱", "펑"));

하위 클래스에서 addAll 메서드를 재정의하지 않거나, 다른 식으로 재정의하면 해결할 수 있다.

하위 클래스가 깨지기 쉬운 이유는 또 존재한다.

<aside> 💡 다행히, 이상의 문제들을 모두 피할 수 있다! → 컴포지션(composition : 구성)

</aside>