I would like to be able to read and write (get and set) certain fields for a bunch of related but different classes without knowing what type of concrete class they are exactly. All I know is that they have some types of parameters that I would like to be able to generically access and modify. And given I don’t know what concrete type the class is I don’t know up-front what the specific parameter types of each are either.
- I think the following approach would work, but is it good enough / what problems might it have?
- Or are there better approaches / or even established design patterns for this issue?
A Superclass to Allow Generic Configurability
public abstract class ParametrizerBase<P1, P2> {
public P1 Param1;
public P2 Param2;
}
Some Concrete Class with Specific Parameters It Needs
public class SomeConcreteClass extends ParametrizerBase<Boolean, String> {
public SomeConcreteClass(Boolean enabled, String task){
Param1 = enabled;
Param2 = task;
}
// ... does something with the parameter data
}
Another Concrete Class with Different Types of Data
public class AnotherConcreteClass extends ParametrizerBase<Integer, Date> {
public AnotherConcreteClass(Integer numberOfItems, Date when){
Param1 = numberOfItems;
Param2 = when;
}
// ... does something with the data it holds
}
Example Usage
ArrayList<ParametrizerBase> list;
public void initSomewhere() {
SomeConcreteClass some = new SomeConcreteClass(true,"Smth");
AnotherConcreteClass another = new AnotherConcreteClass(5, new Date());
list = new ArrayList<ParametrizerBase>();
list.add(some);
list.add(another);
}
public void provideDataElsewhere() {
for (ParametrizerBase concrete : list) {
String param1Type = concrete.Param1.getClass().getName();
if (param1Type.contains("Boolean")) {
Boolean value = concrete.Param1;
// Now could let user modify this Boolean with a checkbox
// and if they do modify, then write it to concrete.Param1 = ...
// All without knowing what Param1 is (generic configuration)
} else if (param1Type.contains("Integer")) {
Integer value = concrete.Param1;
// ...
} // ...
// Same for Param2 ...
}
}
Use a Java interface to describe the getters and setters. Have all the concrete classes implement this interface. Cast the objects to be the interface type, and call the getters and setters as needed.