St.Antario
St.Antario

Reputation: 27425

Overriding list and Java practice

I have three classes (The number will be probably grow in the future):

public inteface Base{ }

public class Select implements Base{ }

public class Ast implements Base{ }

public class Gt implements Base{ }

I also need in a List class

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

The reason why I did this was the fact that I don't want anyone to adds elements via a pointer to Base. In my concrete situation this would be unsafe.

But the disadvantage is that it will be discovered only at runtime.

I also need to iterate over the list.

Is it a good practice to do such things?

Upvotes: 11

Views: 1535

Answers (2)

aioobe
aioobe

Reputation: 421130

Using an interface is fine. (Turning Base into an abstract class won't buy you anything here.)

You should favor composition over inheritance here though, and implement Iterable<Base> to be able to use it in enhanced for loops etc.

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

You can then iterate over the list as follows:

for (Base b : yourBaseList) {
    ...
}

Upvotes: 12

membersound
membersound

Reputation: 86855

You could make Base an abstract class, as these could never be instantiated, your list would be safe.

My the way: I really don't understand why you would like to throw an exception for add(Base b) when base is an interface which itself can never be an object.

Otherwise, use delegate/wrapper pattern, means: Do not extend ArrayList, but create a class holding an ArrayList.

class BaseList {
    private List<Base> list = new ArrayList<>();

    public boolean add(Select s) {
         return list.add(s);
    }
    //etc
}

Upvotes: 7

Related Questions