我正在重讀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