Вопрос оформлен под List
, но он легко применим к другим в каркасе коллекций java.Уместно ли распространять список для добавления полей
Например, я бы сказал, что для создания нового подтипа List
необходимо сохранить что-то вроде счетчика дополнений, поскольку оно является неотъемлемой частью операции списка и не изменяет его. список". Что-то вроде этого:
public class ChangeTrackingList<E> extends ArrayList<E> {
private int changeCount;
...
@Override public boolean add(E e) {
changeCount++;
return super.add(e);
}
// other methods likewise overridden as appropriate to track change counter
}
Однако то, что о добавлении дополнительной функциональности из знаний о списке ADT, такие как хранение произвольных данных, связанных с элементом списка? Предполагая, что связанные данные были правильно обработаны, когда элементы добавлены и удалены, конечно. Что-то вроде этого:
public class PayloadList<E> extends ArrayList<E> {
private Object[] payload;
...
public void setData(int index, Object data) {
... // manage 'payload' array
payload[index] = data;
}
public Object getData(int index) {
... // manage 'payload' array, error handling, etc.
return payload[index];
}
}
В этом случае я переделал, что это «просто список», добавив не только дополнительные функции (поведение), но и дополнительное состояние. Разумеется, часть цели спецификации типа и наследования, но есть ли скрытое ограничение (табу, устаревание, плохая практика и т. Д.) На типы коллекций Java для их обработки специально?
Например, при ссылках на этот PayloadList
в качестве java.util.List
один из них будет мутировать и повторять как обычно и игнорировать полезную нагрузку. Это проблематично, когда дело доходит до чего-то вроде настойчивости или копирования, которое не ожидает, что List
несут дополнительные данные, которые необходимо сохранить. Я видел много мест, которые принимают объект, проверьте, чтобы он был «списком», а затем просто обрабатывал его как java.util.List
. Должны ли они вместо этого позволить произвольные вклады приложений для управления конкретными конкретными подтипами?
Поскольку эта реализация постоянно создавала проблемы в срединном разрезе (игнорируя поля подтипа), является ли плохая идея расширять коллекцию таким образом и всегда использовать композицию, когда есть дополнительные данные для управления? Или вместо этого задача сохранения или копирования для учета всех конкретных подтипов, включая дополнительные поля?
Вы знаете, 'list' сам интерфейс, так что только интерфейс может продлить его. То, что вы делаете, это не совсем «создание чего-то, что является« списком », а скорее« создание специального типа «ArrayList». – RealSkeptic
«Оплатить композицию над наследованием», «Дизайн и документ для наследования или запретить». См. «Эффективное Java 2-е издание», пункт 16, в котором обсуждается именно это. – Natix
@RealSkeptic Я имел в виду «продлить» в смысле «is-a» или любой подтип, а не только с ключевым словом 'extends'. Конечно, 'ArrayList' - это конкретный класс, а' List' - это интерфейс; использование «ArrayList» было для примеров, а не для самого сердца вопроса. –