我有三个班级(这个数字将来可能会增长):
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
的指针添加元素。在我的具体情况下,这将是不安全的。
但缺点是它只会在运行时被发现。
我还需要遍历列表。
做这些事是一种好习惯吗?
答案 0 :(得分:12)
使用interface
很好。 (将Base
变成抽象类不会在这里买任何东西。)
你应该在这里支持组合优于继承,并且实现Iterable<Base>
以便能够在增强的for循环等中使用它。
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) {
...
}
答案 1 :(得分:7)
您可以将Base
设为abstract
课程,因为这些课程永远无法实例化,您的列表也是安全的。
我的方式:我真的不明白为什么当base add(Base b)
本身永远不能成为对象时,你想为interface
抛出异常。
否则,使用delegate / wrapper模式,意味着:不要扩展ArrayList
,而是创建一个类一个ArrayList。
class BaseList {
private List<Base> list = new ArrayList<>();
public boolean add(Select s) {
return list.add(s);
}
//etc
}