Я перечитывал статью 18 «Эффективная Java» (2-е издание), предпочитаю интерфейсы абстрактным классам. В этом пункте Джош Блох приводит пример скелетной реализации интерфейса 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. интерфейс, поэтому я не вижу причин для избыточного объявления в абстрактном классе.
Зачем использовать идиому оставлять эти примитивные методы, как их называет г-н Блох, абстрактными? Почему бы просто не сделать это:
// Скелетная реализация публичный абстрактный класс AbstractMapEntry реализует 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) из классов, предназначенных для наследования, поскольку это делает суперкласс уязвимым для изменений, сделанных подклассами. Может быть, это вопрос мнения, но я надеялся определить, есть ли в этой истории что-то еще, поскольку Блох на самом деле не останавливается на этом в книге.