Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative to instanceof approach in this case

Hello I'm wondering what would be some more elegant alternatives to something like this:

class Base...

class A extends Base...

class B extends Base...

//iterator of colection containing mixed As and Bs i want to remowe Bs and do omething with As
while(iterator.hasNext()) {
    Base next = iterator.next();
    if(next instanceof A) // do something
    if(next instanceof B)
        iterator.remove();
}

Sow what are the alternatives...

Thank you for advices.

edit: Base class may have many subclasses not just two and their numbers may grow in time

like image 467
Jax Avatar asked Nov 06 '22 02:11

Jax


2 Answers

You can create methods in Base and override them in A and B.

For example:

class Base{
    public boolean shouldRemove(){
        return false;
    }
    public void doSomething(){
    }
}

class A extends Base{
    @Override
    public void doSomething() {            
    }
}

class B extends Base{
    @Override
    public boolean shouldRemove() {
        return true;
    }
}

and then you don't need know what class the object is an instance of:

    while(iterator.hasNext()) {
        Base next = iterator.next();
        if(next.shouldRemove()){
            iterator.remove();
        }
        else{
            next.doSomething();
        }
    }
like image 129
dogbane Avatar answered Nov 11 '22 11:11

dogbane


Do you really need to remove them from the list? Why don't you just have the method to do something in the Base class (doing nothing) and then just override it do to what you want on class A.

class Base{
    public void doSomething(){
    }
}


class A extends Base{
    @Override
    public void doSomething(){
        // do something
    }
}

Then you could just iterate over the list and calling the method doSomething on all objects.

for(Base base : list) {
    base.doSomething();
}

This way only the classes that have overridden the doSomething() method will actually do something. All the other classes will just execute the dummy implementation in the Base class.

If Base was an abstract class you could declare the doSomething() as abstract and have the extending classes implement it. With this approach all classes would have to implement the method and classes for which you don't want any computation to be performed you would just provide a dummy implementation of that method. Alternatively you could even create an interface with the doSomething() method and have (which could even be a better decision) and have the Base class implement it, given that only the extending classes would actually implement the method.

like image 31
Mario Duarte Avatar answered Nov 11 '22 11:11

Mario Duarte