简体   繁体   中英

How to see if an object is an instanceof a class that extends a particular parent in java

I want to be able to check for whether an object is an instanceof a class that extends a particular parent class. Below is the relevant portion of code I'm writing. I want to set the aggType variable based on aggDef being of a particular child type. I know I can't do the following as shown below in the code, but is there a technique I can follow to do this kind of functionality? Unfortunately, proper object oriented design is not an option where I can define an abstract method in the parent and have the children know what type they are as these are proprietary inaccessible internal libraries

    String aggType=null;
    AggDef aggDef = queryAggs.get(aggsKey);
        if(aggDef != null){
           if(aggDef instanceof TermAggDef){
                    aggType = "terms";
                } 
                else if (aggDef instanceof ? extends StatAggDef){
                    aggType = "terms_stats";
                }
                else if (aggDef instanceof RangeAggDef){
                    aggType = "range";
                } else{
                    aggType= "statistical";
                }
            }
     }

The alternative would be the way I have it below which does compile and work. But it's tedious and really ugly. How can this be improved?

String aggType;
AggDef aggDef = queryAggs.get(aggsKey);
if(aggDef != null){

    if(aggDef instanceof TermAggDef){
        aggType = "terms";
    } 
    else if (aggDef instanceof StatAggDef){
        if(aggDef instanceof AvgAggDef){
            aggType= "statistical";
        }else if(aggDef instanceof MaxAggDef){
            aggType= "statistical";
        }else if(aggDef instanceof MinAggDef){
            aggType= "statistical";
        }else if(aggDef instanceof SumAggDef){
            aggType= "statistical";
        } else{
            aggType = "terms_stats";
        }
    }
    else if (aggDef instanceof RangeAggDef){
        aggType = "range";
    }
}

Instead of going through all of these mental gymnastics, why not just write object oriented code, something like:

public abstract class AggDef { // horribly named class
    public abstract Type getType();
...
}

and override that method on each subclass.

public class StatAggDef extends AggDef { 

    @Override
    public Type getType() {
        //something concrete, ideally not a String....
    }

}

This is far more extensible when you add new types. Using instanceof is a pretty good indication that you haven't really modeled your application correctly.

Make yourself a Map<Class<? extends AggDef>, String> Map<Class<? extends AggDef>, String> ; populate it; and look it up via aggDef.getClass() instead of the if-else/instanceof chain.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM