学习《Effective java》的过程中,对十六条:复合优先于继承这一条有深刻的印象。
书中用到了一个非常经典的例子来解释这一点:
public class InstrumentedHashSet<E> extends HashSet<E>{
private int addCount = 0;
public InstrumentedHashSet() {
// TODO Auto-generated constructor stub
}
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;
}
public static void main(String[] args) {
InstrumentedHashSet<String> s = new InstrumentedHashSet<String>();
s.addAll(Arrays.asList("snap","c","po"));
System.out.println(s.getAddCount());
}
期望返回的结构是3,而实际返回的结果是6,对于这样的结构,书中也给出了非常详细的解释,就是HashSet的文档中并没有告诉我们,它的addAll方法是基于add方法来实现的,我们在Override add方法的时候,又进行addCount++
自然也就出现了错误的结果。书中也给了一个复合的例子,具体的我就不贴代码出来了。说到这,我想说下自己的一点点理解把吧:
复合(has-a)和继承(is-a)两者在意义上有明显的区别:
1.继承明确了基类和子类的职责关系,基类(A)要实现的功能,子类(B)也要实现,但是实现方式可以有区别。
2.复合则属于互相平行关系,以A和B来说,A实现的功能,B不必去实现,但是B在实现所属业务的过程中可以调用A的方法。
3.根据业务需要,使用不同的方式才是最合适的方式。业务上明确A和B是继承关系的,则使用继承。否则,这个时候就需要去考虑下,是否还应该使用继承,是否使用复合更合适。
简单的归纳了三条个人理解,希望大家有更好的理解的时候能不吝留言,非常感谢。