最近在看Effective Java这本书,发现自己的水平水平差到家了,其中很多的java语法都搞错了,比如:子类重写了父类的add()与addAll()方法,
父类中的addAll()方法中又调用了add()方法,这时如果我们在子类总的addAll方法中调用super.addAll()方法时,由于其中addAll()方法中调用
add()方法,但是子类中重写了add()方法,所有这时调用的是子类的add方法而不是父类的add方法
我是这样理解的,当执行super.addAll()方法时,编译器会把父类中的addAll()方法代码添过来,等到执行add()方法时就会执行当前类中的add()方法,也就是子类
1.接下来步入主题,分析一下书中的例子,假设我们现在使用到了HashSet,我们想要知道它被创建到现在被添加了多少元素。实现很简单,我们可以
继承HashSet,并添加一个count属性来记录添加的元素个数,每当添加一个,count加1;如下面代码
public class InstrumentHashSet<E> extends HashSet<E>{
private int count;
@Override
public boolean add(E e) {
// TODO Auto-generated method stub
count++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
// TODO Auto-generated method stub
int size = c.size();
count+= size;
return super.addAll(c);
}
public int getCount(){
return count;
}
public static void main(String[] args) {
InstrumentHashSet<String> s = new InstrumentHashSet<String>();
// s.add("xinwa");
// System.out.println("hashSet中的count为"+s.getCount());
s.addAll(Arrays.asList("xinwa1","xinwa2","xinwa3"));
System.out.println("hashSet中的count为"+s.getCount());
}
}
在上面的事例中,我们添加了3个元素,我们来运行一个程序查看一下
count中的值,运行程序count值为6,这是怎么回事呢,其实,HashSet
中的addAll()方法内部调用了add()来实现,当调用add方法时会执行被子类中的add方法,所有才会有count值加倍的情况
2.有一种方法我们可以使用重用来实现
我们可以在新的类中增加一个私有filed,他引用现有类的实类,现有的类成为了变成了新有的类的一个组件。这个实现分为俩部分:类本身和可重用的转发类
public class InstrumentSet<E> extends ForwardingSet<E> {
private int count;
public InstrumentSet(Set<E> s) {
super(s);
}
public boolean add(E e) {
count++;
return super.add(e);
}
public boolean addAll(Collection <? extends E> c){
int size = c.size();
count+= size;
return super.addAll(c);
}
public int getCount(){
return count;
}
public static void main(String[] args) {
InstrumentSet<String> set = new InstrumentSet<String>(new HashSet<String>());
// set.add("xinwa");
// System.out.println(set.getCount());
set.addAll(Arrays.asList("xinwa1","xinwa2","xinwa3"));
System.out.println(set.getCount());
}
}
转发类
public class ForwardingSet<E> implements Set<E>{
private final Set<E> s;
public ForwardingSet(Set<E> s) {
this.s = s;
}
@Override
public int size() {
// TODO Auto-generated method stub
return s.size();
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return s.isEmpty();
}
@Override
public boolean contains(Object o) {
// TODO Auto-generated method stub
return s.contains(o);
}
@Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return s.iterator();
}
@Override
public Object[] toArray() {
// TODO Auto-generated method stub
return s.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
// TODO Auto-generated method stub
return s.toArray(a);
}
@Override
public boolean add(E e) {
// TODO Auto-generated method stub
return s.add(e);
}
@Override
public boolean remove(Object o) {
// TODO Auto-generated method stub
return s.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
// TODO Auto-generated method stub
return s.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends E> c) {
// TODO Auto-generated method stub
return s.addAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
// TODO Auto-generated method stub
return s.retainAll(c);
}
@Override
public boolean removeAll(Collection<?> c) {
// TODO Auto-generated method stub
return c.removeAll(c);
}
@Override
public void clear() {
// TODO Auto-generated method stub
}
}
由于我们在ForwardingSet内部建个了一个Setfiled,所有的添加都是同他
来实现的,并不参与count++的逻辑实现,这样就避免了继承所带来的例子