dabadaba
dabadaba

Reputation: 9532

How to enforce that a collection of objects are instances of the same child class

Let's say we have the following class hierarchy:

public abstract class Parent {
    // body of parent
}

public class ChildA {
    // body of child A
}

public class ChildB {
    // body of child B
}

And we have a collection of objects of type Parent and a way to feed that collection:

List<Parent> list;

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

When we start adding elements to that list, how can we ensure that they are only instances of the same class? Either instances of ChildA or instances of ChildB, but not both.

Upvotes: 0

Views: 72

Answers (4)

Sari Alalem
Sari Alalem

Reputation: 870

Just extend ArrayList for example like this:

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);
    }
}

Then just use the regular add function to fill it up

Upvotes: 1

Landei
Landei

Reputation: 54584

As the type of the list would depend on the first element added to it, there is no way to have a compile time check. The only thing you could do would be an ugly runtime check:

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);
    }
}

However, I don't think you should use such an abomination. You should rethink your design instead.

Upvotes: 1

Simon
Simon

Reputation: 6363

You could do something like

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

Upvotes: 2

GhostCat
GhostCat

Reputation: 140525

What you are asking for doesn't make sense.

If your list should only contain objects of a certain class; then use the generics to say so.

There is no point in telling the compiler "here is a list of fruit"; to then ask: "and how do I turn that list into one that only takes apples, but not bananas"?! The point is to declare it to be a "list of apples" initially; then the compiler can do all the checking for you.

Upvotes: 1

Related Questions