Переопределение списка и практика Java
У меня есть три класса (число, вероятно, возрастет в будущем):
public inteface Base{ }
public class Select implements Base{ }
public class Ast implements Base{ }
public class Gt implements Base{ }
Мне также нужен класс List
BaseList extends ArrayList<Base>{
public boolean add(Base b){
throw new UnsupportedOperationException("You should use add%ConcereteBaseType% method instead");
}
public boolean add(Select s){ }
public boolean add(Ast a){ }
public boolean add(Gt g){ }
}
Причина, по которой я делал это, был тот факт, что я не хочу, чтобы кто-то добавлял элементы через указатель на Base
. В моей конкретной ситуации это было бы небезопасно.
Но недостатком является то, что он будет обнаружен только во время выполнения.
Мне также нужно перебирать список.
Хорошо ли это делать?
Ответы
Ответ 1
Использование interface
в порядке. (Включение Base
в абстрактный класс не купит вам ничего здесь.)
Здесь вы должны отдать предпочтение композиции над наследованием и реализовать Iterable<Base>
, чтобы иметь возможность использовать ее в расширенных для циклов и т.д.
class BaseList implements Iterable<Base> {
private List<Base> list = new ArrayList<>();
public boolean add(Select s) {
return list.add(s);
}
public boolean add(Ast a) {
return list.add(a);
}
public boolean add(Gt gt) {
return list.add(gt);
}
@Override
public Iterator<Base> iterator() {
return Collections.unmodifiableList(list).iterator();
}
}
Затем вы можете перебирать список следующим образом:
for (Base b : yourBaseList) {
...
}
Ответ 2
Вы можете сделать класс Base
a abstract
, поскольку они никогда не могут быть созданы, ваш список будет безопасным.
Мой путь: я действительно не понимаю, почему вы хотели бы генерировать исключение для add(Base b)
, когда base является interface
, который сам по себе никогда не может быть объектом.
В противном случае используйте шаблон delegate/wrapper, значит: не расширяйте ArrayList
, а создайте класс, содержащий ArrayList.
class BaseList {
private List<Base> list = new ArrayList<>();
public boolean add(Select s) {
return list.add(s);
}
//etc
}