java 复合优于重用

最近在看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++的逻辑实现,这样就避免了继承所带来的例子

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值