Skip to content
Advertisement

Storing Objects of multiple classes in an Array List, then accessing their attributes

I have class of (sub)Objects

public class SubObjects {
    
    int depth;
    
    public SubObjects(int d) {
        this.depth = d;
    }
}

And a class of Objects

public class Objects {
    
    private int height;
    private int width;
    ArrayList<SubObjects> liste;
    
    public Objects(int h, int w) {
        this.height = h;
        this.width = w;
        this.liste = new ArrayList<>();
    }
}

The Objects hold the values height and width and an ArrayList of SubObjects. This works as intended, I do however want to store multiple types of SubObjects from different classes in these ArrayLists.

After a bit of googling I changed the Objects class to

public class Objects {
    
    private int height;
    private int width;
    ArrayList<Object> liste;
    
    public Objects(int h, int w) {
        this.height = h;
        this.width = w;
        this.liste = new ArrayList<Object>();
    }
}

This allows me, as I intended, to store Objects from a second class SubObjects2 inside the ArrayList

public class SubObjects2 {
    
    int weight;
    
    public SubObjects2(int weight) {
        this.weight = weight;
    }
}

This was great and I thought I had solved it, but then I ran the main class and while I, with the earlier implementation could return values with a getter from the objects in the ArrayList

... liste.get(i).depth (in a for loop)

The same query now returns the following error

Unresolved compilation problem: 
    depth cannot be resolved or is not a field

How do I access the values inside the SubObjects that are stored in the ArrayList now?

Advertisement

Answer

Your problem is that the Object class has no field with the name depth and only SubObject has this attribute

If all of your types have common attributes that you want to get it, you can create an interface and all of them should implement it it for example

interface SubObject {
    int value();
}

public class SubObjects implements SubObject {

    ...

    @Override
    public int value() {
        return depth;
    }
}

public class SubObjects2 implements SubObject {

    ...

    @Override
    public int value() {
        return weight;
    }
}
       

and now you will create a list of SubObject and in the loop, it will be

for (int i = 0; i < lists.size() ; i++) {
    int value = lists.get(i).value();
}

The other solution is to check for the type and cast it before getting the value for example

List<Object> lists = new ArrayList<>();
for (int i = 0 ; i < lists.size(); i++) {
    Object object = lists.get(i);
    if (object.getClass() == SubObjects.class) {
        SubObjects subObject = (SubObjects) object;
        int depth = subObject.depth;
    }
    
    else if if (object.getClass() == SubObjects2.class) {
        SubObjects2 subObject2 = (SubObjects2) object;
        int weight = subObject2.weight;
    }
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement