EFFECTIVE JAVA 类和接口
第十六条:复合优先于继承
//这是一个不好的类---执行的结果 addCount = 4(addAll的实现依赖于HashSet的add方法,InstrumentHashSet方法重写了add方法有执行了addCount++)
public class InstrumentHashSet<E> extends HashSet<E> { private int addCount = 0 ; @Override public boolean add(E e) { System.out.println("子类添加 "); addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount+= c.size(); System.out.println("添加所有 "); return super.addAll(c); } public static void main(String[] args) { InstrumentHashSet s = new InstrumentHashSet<String>(); s.addAll(Arrays.asList("1","2")); System.out.println(s.addCount); } }
//wrapper class --- use composition in place of inheritance 因为每一个InstrumentedSet 实例都把另一个Set实例包装起来了,所以InstrumentedSet类被称为包装类(这正是Decorator模式)---注意这不是委托(delegation)除非包装对象把自身传递给被包装对象
public class InstrumentedSet<E> extends ForwardingSet<E> { private int addCount = 0 ; /** * 描述: 构造方法 * @param s */ public InstrumentedSet(Set<E> s) { super(s); } @Override public boolean add(E e) { System.out.println("我执行了InstrumentedSet 的add"); addCount++; return super.add(e); } @Override public boolean addAll(Collection<? extends E> c) { System.out.println("执行 addAll c.size= " + c.size() +" count = "+ addCount); addCount += c.size(); return super.addAll(c); } public int getAddcount(){ return addCount; } public static void main(String[] args) { HashSet<Integer> s = new HashSet<Integer>(); s.add(1); s.add(2); HashSet<Integer> s1 = new HashSet<Integer>(); s1.add(3); s1.add(4); InstrumentedSet is = new InstrumentedSet<Integer>(s); // is.add(3); is.addAll(s1); System.out.println(is.getAddcount()); } }
//forwarding class 里面的转发方法称为转发方法(forwarding method) 这样得到的类非常的稳固,它不依赖于现有类的实现细节,即使现有的类添加了新的方法,也不会影响新的类
public class ForwardingSet<E> implements Set<E> { private Set<E> s ; /** * 描述: 构造方法 */ public ForwardingSet(Set<E> s) { System.out.println("初始化s,类型:"+s.getClass()); this.s = s; } @Override public int size() { return s.size(); } @Override public boolean isEmpty() { return s.isEmpty(); } @Override public boolean contains(Object o) { return s.contains(o); } @Override public Iterator<E> iterator() { return s.iterator(); } @Override public Object[] toArray() { return s.toArray(); } @Override public <T> T[] toArray(T[] a) { return s.toArray(a); } @Override public boolean add(E e) { System.out.println("我执行了ForwardingSet 的add"); return s.add(e); } @Override public boolean remove(Object o) { return s.remove(o); } @Override public boolean containsAll(Collection<?> c) { return s.containsAll(c); } @Override public boolean addAll(Collection<? extends E> c) { System.out.println("我执行了addAll"); return s.addAll(c); } @Override public boolean retainAll(Collection<?> c) { return s.retainAll(c); } @Override public boolean removeAll(Collection<?> c) { return s.removeAll(c); } @Override public void clear() { s.clear(); } }
测试中的addAll方法实际上走的是HashSet的add方法