这个,不管是什么书都会这样说,因为常常我们并不需要继承,而只是想把类进行一定的扩展,而我们想扩展的属性或方法对应的类都有,这个时候如果两者是is a的关系,这种关系是确实存在的,那么就可以使用继承,不然一般都是建议使用复合。
如果我们队一个类进行继承的时候,我们如果对其内部的逻辑并不十分了解的时候,直接继承的结果就是可能有些方法是类自己内部调用的,而我们在继承这个方法的时候,可能会覆盖某些方法,或者重载某些方法,或者加上了一些自己的逻辑,这样就会吧原来的逻辑和我们自己的逻辑混杂起来,并且如果继承的类内部有使用这个类的话,那么就会调用我们自己写的部分逻辑,那么结果就变得不可预料了
这里的建议是使用包装类模式
package cn.xf.cp.ch02.item16;import java.util.Collection; import java.util.Iterator; import java.util.Set;public class ForwardingSet<E> implements Set<E> {/*** 这个类作为转发类,内部通过复合的方式把set作为一个组件*/private final Set<E> s;public ForwardingSet(Set<E> s){this.s = s;}@Overridepublic int size(){return s.size();}@Overridepublic boolean isEmpty(){return s.isEmpty();}@Overridepublic boolean contains(Object o){return s.contains(o);}@Overridepublic Iterator<E> iterator(){return s.iterator();}@Overridepublic Object[] toArray(){return s.toArray();}@Overridepublic <T> T[] toArray(T[] a){return s.toArray(a);}@Overridepublic boolean add(E e){return s.add(e);}@Overridepublic boolean remove(Object o){return s.remove(o);}@Overridepublic boolean containsAll(Collection<?> c){return s.containsAll(c);}@Overridepublic boolean addAll(Collection<? extends E> c){return s.addAll(c);}@Overridepublic boolean retainAll(Collection<?> c){return s.retainAll(c);}@Overridepublic boolean removeAll(Collection<?> c){return s.removeAll(c);}@Overridepublic void clear(){s.clear();}}
这样,我们在每个方法中调用了私有成员的方法,那么私有成员对外部就是不可见的,它里面的方法就不会和外面的方法混杂起来
package cn.xf.cp.ch02.item16;import java.util.Collection; import java.util.Set;/*** *功能:包装类*时间:下午9:58:36*文件:InstrumentedSet.java *@author xiaof ** @param <E>*/ public class InstrumentedSet<E> extends ForwardingSet<E> {private int addCount = 0; //用来统计set添加了多少元素public InstrumentedSet(Set<E> s){super(s);}@Overridepublic boolean add(E e){++addCount;return super.add(e);}@Overridepublic boolean addAll(Collection<? extends E> c){addCount += c.size();return super.addAll(c);}public int getAddCount(){return addCount;}}