Reputation: 16309
I have an abstract class that has one field whose type can vary between its subclassses. For example:
public abstract class ABCModel {
protected String foo;
protected String bar;
protected ? baz;
}
In my implementations, baz
may be an Int or a Float. For example:
public class ModelFoo {
protected Int baz;
}
public class Modelbar {
protected Float baz;
}
First, let me ask if this is a valid/accepted design pattern in Java? I've chosen this pattern because I want to abstract-away most of the tedious boilerplate in the shared methods.
Depending on how I implement it, I get variations of this error:
incompatible types: CAP#1 cannot be converted to BidAsk
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
This leads me to believe I'm doing something wrong.
The example I posted is a bit trivial compared to my actual code, in which this generic is buried in a nested hashtable. I'm trying to decide if what I'm doing is a smart design in Java or not before getting too invested.
I've tried searching for this, but probably am not articulating the terminology correctly.
Thanks.
Upvotes: 4
Views: 4030
Reputation: 11619
What you are asking is the basic usage of generics:
public abstract class ABCModel<T> {
private T baz;
public T getBaz() { return baz; }
public void setBaz(T baz) { this.baz = baz; }
}
public class IntModel extends ABCModel<Integer> { // baz is of type Integer
}
public class FloatModel extends ABCModel<Float> { // baz is of type Float
}
IntModel m1 = new IntModel();
Integer i = m1.getBaz();
FloatModel m2 = new FloatModel();
Float f = m2.getBaz();
Upvotes: 5
Reputation: 603
This is an accepted pattern, but you should be more specific about your generics :
public abstract class ABCModel<T extends Number> {
protected String foo;
protected String bar;
protected T baz;
public T getBaz() {
return baz;
}
}
After that you can extend your model :
public class ModelFoo extends ABCModel<Integer> {
// No need to specify again baz.
}
Upvotes: 2
Reputation: 63104
Fields cannot be overridden in Java. You can however use methods with generics.
public abstract class ABCModel<T> {
public abstract T getBaz();
}
Then
public class ModelFoo extends ABCModel<Integer> {
public Integer getBaz() {
...
}
}
Upvotes: 1