覆盖列表和Java实践

时间:2015-05-22 09:05:16

标签: java list

我有三个班级(这个数字将来可能会增长):

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的指针添加元素。在我的具体情况下,这将是不安全的。

但缺点是它只会在运行时被发现。

我还需要遍历列表。

做这些事是一种好习惯吗?

2 个答案:

答案 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
}