Check attribute of a subclass

2020-05-08 07:20发布

问题:

I stumbled across that situation but I don't know how to handle it the right way:

class Myclass { }
class MyclassWithAwesomeStuff extends Myclass {
    public boolean awesomeStuff;
}

I'm saving the Myclass objects in an arraylist and iterate later through this list:

for(Myclass m : list) {
    //here I want to check if awesomeStuff is true, in case it is a MyclasswithAwesomeStuff
}

The problem here is: the parent class Myclass doesn't know the awesomeStuff attribute (and it shouldn't because that is a feature that comes only with the derived class). But how can I manage this? The problem is, that the arraylist contains Myclass and MyclassWithAwesomeStuff elements and the foreach loop casts them always to Myclass.

I wonder if this is a design failure?

//EDIT:

Okay, to make my question a little bit more tangible, here more infos. I'm trying to build a small coffee shop:

class Coffee { }
class CoffeeMix extends Coffee {
    public boolean shaken;
}

I'm saving the coffee items in an array list:

ArrayList<Coffee> coffees = new ArrayList<Coffee>();

So in this array list exist normal coffee objects and coffee mix objects. Now I want to display all coffee mix objects, that are shaken:

for(Coffee c : coffees) {
    //here is the same problem as above
}

As I can see from the answers/comments: instanceof seems to be a bad idea, because it screws the idea behind oo up and an interface that both classes implement is a bad idea too, because a normal coffee can not be shaken. So how to handle this?

回答1:

Test if m is a MyclassWithAwesomeStuff with the instanceof operator.

if (m instanceof MyclassWithAwesomeStuff)
{
    MyclassWithAwesomeStuff mwas = (MyclassWithAwesomeStuff) m;
    // Now you can access "awesomeStuff" with "mwas"
}


回答2:

Just use an interface:

interface AwesomeStuffable{

    public boolean isAwesome();

}

let your classes implement it:

class MyClass implements AwesomeStuffable{

  public boolean isAwesome(){

    //your logic here

  }

}

And let your ArrayList hold just AwesomeStuffable objects.



回答3:

Just to get yourself unblocked, you can do the following:

if (m instanceof MyClassWithAwesomeStuff) {
    if (((MyClassWithAwesomeStuff) m).awesomeStuff) {

    }
}

But, using instanceof defeats the purpose of inheritance and it appears to be a design flaw to have a need to check for this flag for only some objects in list in your code. If you expand the context, probably something better can be suggested.



标签: java class