我正在重读Effective Java(第2版)第18项prefer interfaces to abstract classes。在该项目乔希布洛赫提供的骨干实现Map.Entry<K,V>
接口的一个例子:接口的骨架实现中的抽象方法
// Skeletal Implementation
public abstract class AbstractMapEntry<K,V>
implements Map.Entry<K,V> {
// Primitive operations
public abstract K getKey();
public abstract V getValue();
// ... remainder omitted
}
两个问题从这个例子干:
- 为什么信息getKey和getValue明确声明这里的抽象方法?它们是Map.Entry接口的一部分,所以我没有看到抽象类中冗余声明的原因。
为什么用布洛赫先生提到的这些原始方法来表达抽象的成语?为什么不这样做:
//骨架实现 public abstract class AbstractMapEntry implements Map.Entry { private K key;私人V值为 ;
// Primitive operations public K getKey() {return key;} public V getValue() {return value;} // ... remainder omitted
}
这样做的好处是,每个子类没有定义自己的字段集,并且仍然可以访问他们的存取键和值。如果一个子类真的需要为访问者定义自己的行为,那么它可以直接实现Map.Entry接口。另一个缺点是,在由骨骼实现提供的equals方法,将抽象访问被称为:
// Implements the general contract of Map.Entry.equals
@Override public boolean equals(Object o) {
if (o == this)
return true;
if (! (o instanceof Map.Entry))
return false;
Map.Entry<?,?> arg = (Map.Entry) o;
return equals(getKey(), arg.getKey()) &&
equals(getValue(), arg.getValue());
}
布洛赫警告不要从设计继承的类调用重写的方法(17项),因为它离开超容易由子类进行的更改。 也许这是一个意见问题,但我希望能够确定是否有更多的故事,因为布洛赫在书中没有详细说明这一点。
错误,你似乎完全忽略了这个问题... – 2008-10-25 23:39:22