RyanS
RyanS

Reputation: 85

How to define a field to have multiple types?

I have a class that I wish to take two different types of inputs (via one constructor argument) and process polymorphically. Everything in the class is the same except for the handling of these two different input types, and I don't wish to duplicate all the code just due to the need for one field to have variable type. I guess my question is how to define a field to have a variable type? Or is this just bad practice? See my simple example below where I use *Map or Set* as a placeholder representing the variable type I wish to use for a field or method return type.

public abstract class ReturnTwoTypes {  

    public abstract Map<String,Double> *or* Set<String> runProgram();

}




private class ReturnSetType extends ReturnTwoTypes{

    @Override
    public Set<String> runProgram(){

        return new TreeSet<String>();
    }

}




private class ReturnMapType extends ReturnTwoTypes{

    @Override
    public Map<String, Double> runProgram(){

        return new TreeMap<String, Double>();
    }

}




private class UsesReturnTwoTypes{

    //This class has a bunch of code I wish to reuse by not defining separate classes for both the Map and Set version of the MapOrSet field

    private ReturnTwoTypes twotypes;
    private Map<String,Double> *or* Set<String> mapOrSet;

    public UsesReturnTwoType( ReturnTwoTypes twotypes ){

        this.twotypes = twotypes;
    }

    public void runProgram(){

        mapOrSet = twotypes.runProgram();
    }

}

Upvotes: 1

Views: 7448

Answers (3)

El Bert
El Bert

Reputation: 3026

An attribute can not have multiple types, using a generic Object as suggested in comments and answer is really dirty. You could either use generic methods or have your method return a custom object.

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691685

Make your class generic:

public abstract class ReturnTwoTypes<T> {  
    public abstract T runProgram();
}

private class ReturnSetType extends ReturnTwoTypes<Set<String>> {

    @Override
    public Set<String> runProgram(){
        return new TreeSet<String>();
    }
}

Upvotes: 6

An SO User
An SO User

Reputation: 24998

You could declare them as Object and store whatever reference you want. Then you can use instanceof or getClass().getName() to check what is in there and take action appropriately.

Upvotes: -1

Related Questions