***接口和抽象类同样可以用来定义多个实现的类型,然而,接口通常是最佳途径.***
这条规则有个例外 – 当演变的容易性比灵活性和功能性更为重要的时候,应该用抽象来定义类型
,但前提是必须理解并且可以接受这些局限性.
接口
1.现在的类可以很容易被更新,以实现新的接口
2.接口式定义mixin的理想选择
3.接口允许我们构造非层次结构的类型框架
public interface ISinger {
AudioClip sing(Song song);
}
public interface ISongWriter {
Song compose(boolean hit);//构成 冲击
}
定义一个接口同时实现ISinger和ISongWriter
public interface ISingerSongWriter extends ISinger,ISongWriter{
AudioClip strum();//音频剪辑弹奏
void actSensitive();//行为敏感
}
抽象类
1.如果使用抽象类定义类型,那么必须使用继承的手段来增加功能
2.演变的容易性比灵活性和功能性更为重要的时候,应该用抽象来定义类型
3.抽象类的演变比接口的演变容易得多
通过对导出的每个重要接口都提供一个抽象的骨架实现类,把接口和抽象类的优点结合起来
接口的作用仍然是定义类型,但是骨架实现类接管了所有域接口实现相关的工作
骨架实现–
static List<Integer> intArrayAsList(final int[] a){
if(a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
public Integer get(int i){
//自动装箱
return a[i];
}
public Integer set(int i,int val){
int oldval = a[i];
//自动拆箱
a[i] = val;
自动装箱
return oldval;
}
public int size(){
return a.length;
}
};
}
骨架为抽象类提供了实现上的帮助,但又不强加抽象类被用作类型定义时所特有的严格限制
模拟多重继承:实现了接口的类可以把对于接口的方法调用,转发到一个内部私有类的实例上,这个内部私有类扩展了股价实现类
编写骨架方法必须确定哪些方法是最基本的,其他的方法可以根据他们来实现.这些基本的方法将成为股价实现类中的抽象方法,
然后必须为接口中所有其他的方法提供具体的实现.
–例如Map.Entry接口的骨架实现类
public abstract AbstractMapEntry<K,V> implements Map.Entry<K,V> {
public abstract K getKey();
public abstract V getValue();
@Override
public V setValue(V value) {
// TODO Auto-generated method stub
return (V) new UnsupportedOperationException();
}
@Override
public boolean equals(Object o){
if(o==this)
return true;
if(!(o instanceof Map.Entry))
return false;
Map.Entry<K, V> arg = (Entry<K, V>) o;
return equals(getKey(),arg.getKey())&&
equals(getValue(),arg.getValue());
}
private boolean equals(Object o1,Object o2){
return o1 == null? o2 == null: o1.equals(o2);
}
@Override
public int hashCode(){
return hashCode(getKey())^hashCode(getValue());
}
private int hashCode(Object o){
return o == null?0:o.hashCode();
}
}