复合优先于继承

出发点:

    与方法调用不同的是,继承打破了封装性。子类依赖于超类中特定功能的实现细节。超类可能跟随着版本不断的发生变化,如果真的发生变化,子类可能会受到影响。
    对于专门为了继承设计、并且具有很好的文档说明的类来说,使用继承也是非常安全的,然而对于普通的类来说,进行跨包继承都是非常危险的。
    这种情况多出现与一个类扩展另一个类的时候,不包括类实现接口以及接口的多继承。

问题案例:

    一个程序使用了 HashSet,为了调优该程序的性能,需要查询HashSet,统计他被创建以来添加了多少个元素,当然在HashSet中可以增加元素的方法无非:add和addAll,因此需要覆盖这两个方法。
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

public class InstrumentedHashSet<E> extends HashSet<E> {

	private int count = 0;

	public InstrumentedHashSet() {

	}

	public InstrumentedHashSet(int initCap, float loadFactor) {
		super(initCap, loadFactor);
	}

	@Override
	public boolean add(E e) {
		count++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection<? extends E> c) {
		count += c.size();
		return super.addAll(c);
	}

	public int getCount() {
		return count;
	}

	public static void main(String[] args) {
		InstrumentedHashSet<String> hashSet = new InstrumentedHashSet<String>();
		hashSet.addAll(Arrays.asList("A", "B", "C"));
		System.out.println(hashSet.getCount());
	}
}

运行结果:

我们第一反应结果是3,可是程序运行后结果却是6,这是为什么呢?

原因:

InstrumentedHashSet类main方法中hashSet.addAll(Arrays.asList("A", "B", "C"));   
调用本类中@Override public boolean addAll(Collection<? extends E> c) {}此方法。
但是这个方法中return super.addAll(c);调用了HashSet的addAll实现。让我们看看这个实现。
 public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }
程序在此调用了InstrumentedHashSet覆盖的add方法,count又会自增一次。结果当然为6。
————————————————————————————————————————————————————

复合优先于继承

  我们可以创建一个新的类,在新的类中添加一个私有域,他引用现有类的一个实例。这种设计叫做复合
  因此现有的类变成了新类的一个组件,新类中的每个实例方法都可以调用被包含的现有的类中对应的方法。并返回他的结果,这就是转发
   新类中的方法被称为 转发方法。

具体实现如下:

现有类:
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class InstrumentedSet<E> extends NewSet {
	private int count = 0;

	public InstrumentedSet(Set<E> set) {
		super(set);
	}

	@Override
	public boolean add(Object e) {
		count++;
		return super.add(e);
	}

	@Override
	public boolean addAll(Collection c) {
		count += c.size();
		return super.addAll(c);
	}

	public int getCount() {
		return count;
	}

	public static void main(String[] args) {
		InstrumentedSet<String> hashSet = new InstrumentedSet<String>(new HashSet<String>());
		hashSet.addAll(Arrays.asList("a", "b", "c"));
		System.out.println(hashSet.getCount());
	}
}
新类:
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

/**
 * ClassName: NewSet
 * 
 * @Description: 新类
 * @author QingFeng
 * @date 2018年3月22日
 */
public class NewSet<E> implements Set<E> {

	private final Set<E> s; // 在新的类中添加一个私有域

	public NewSet(Set<E> s) { // 引用InstrumentedSet的一个实例,InstrumentedSet类成为此类的一个组件
		this.s = s;
	}

	public void clear() {
		s.clear();
	}

	public boolean contains(Object o) {
		return s.contains(o);
	}

	public boolean isEmpty() {
		return s.isEmpty();
	}

	public int size() {
		return s.size();
	}

	public Iterator<E> iterator() {
		return s.iterator();
	}

	public boolean add(E e) {
		return s.add(e);
	}

	public boolean remove(Object o) {
		return s.remove(o);
	}

	public boolean containsAll(Collection<?> c) {
		return s.containsAll(c);
	}

	public boolean addAll(Collection<? extends E> c) {
		return s.addAll(c);
	}

	public boolean removeAll(Collection<?> c) {
		return s.removeAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return s.retainAll(c);
	}

	public Object[] toArray() {
		return s.toArray();
	}

	public <T> T[] toArray(T[] a) {
		return s.toArray(a);
	}

	@Override
	public boolean equals(Object o) {
		return s.equals(o);
	}

	@Override
	public int hashCode() {
		return s.hashCode();
	}

	@Override
	public String toString() {
		return s.toString();
	}

}

运行结果:毫无疑问结果为6



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值