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方法

原文地址:https://www.cnblogs.com/sallet/p/4443663.html