如何强制对象集合是同一子类的实例

时间:2016-04-12 09:22:52

标签: java inheritance class-hierarchy

假设我们有以下类层次结构:

public abstract class Parent {
    // body of parent
}

public class ChildA {
    // body of child A
}

public class ChildB {
    // body of child B
}

我们有一组Parent类型的对象以及一种提供该集合的方法:

List<Parent> list;

public void add(Parent newParent) {
    list.add(newParents);
}

当我们开始向该列表添加元素时,我们如何确保它们只是同一个类的实例? ChildA的实例或ChildB的实例,但不是两者。

4 个答案:

答案 0 :(得分:2)

您可以执行类似

的操作
public void add(Parent newParent, Class<? extends Parent> clazz) {
    if(clazz.equals(list.get(0).getClass()) {
        list.add(newParents);
    }
}

答案 1 :(得分:1)

你所要求的是没有意义的。

如果您的列表只包含某个类的对象;然后使用泛型来说出来。

告诉编译器“这里有水果列表”是没有意义的;然后问:“我怎么把那个列表变成只吃苹果而不是香蕉的?”?!关键是最初声明它是一个“苹果列表”;然后编译器可以为你做所有的检查。

答案 2 :(得分:1)

由于列表的类型取决于添加到其中的第一个元素,因此无法进行编译时检查。你唯一能做的就是丑陋的运行时检查:

class Foo {
    List<Parent> list;
    Class<? extends Parent> clazz = null;

    public void add(Parent newParent) {
        if (clazz == null) {
            clazz = newParent.getClass();
        } 
        if (! clazz.isInstance(newParent)) {
            throw new IllegalArgumentException("wrong type");
        }  
        list.add(newParent);
    }
}

然而,我认为你不应该使用这种可憎的东西。你应该重新考虑你的设计。

答案 3 :(得分:1)

只需像这样扩展ArrayList:

public class WhackyArrayList<E> extends ArrayList<E> {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public boolean add(E e) {
        if (this.size() > 0) {
            Object firstElement = this.get(0);
            if (e.getClass().equals(firstElement.getClass())) {
                return super.add(e);
            } else {
                return false;
            }
        }
        return super.add(e);
    }
}

然后只需使用常规添加功能填充