Java, generics and static methods
I would like to have a generic Interpolator class which can interpolate between instances of classes implementing the Interpolatable interface:
interface Interpolatable {
int getDimension();
Iterator <? extends Interpolatable> getIterator(double d);
}
class Coordinate extends AnotherClass implements Interpolatable {
public int getDimension() {return 3;}
public Iterator <Coordinate> getIterator (double d) {…}
}
class Interpolator <T extends Interpolatable> {
Interpolator () {
int dim = T.getDimension();
}
void doSomething (double d) {
Iterator <? extends Interpolatable> it = T.getIterator(d);
Interpolatable t = it.next();
…
}
}
Of course, the compiler complains about T.getDimension()
and T.getIterator(d)
:
Cannot make a static reference to the non-static method getDimension()/getIterator(double) from the type Interpolatable.
However, the two methods cannot be made static, because they are defi开发者_如何转开发ned in an interface. And at the time I would use them in Interpolator, I do not have an instance of Coordinate (or any Interpolatable) available.
Any suggestions?
(I understand why interface methods cannot be static; I just lack an idea how to elegantly solve a problem like this.)
Because of type erasure, you cannot do much with the generic type at runtime. You need to keep an instance or class object around:
class Interpolator <T extends Interpolatable> {
private final T target;
Interpolator (T target) {
this.target = target;
int dim = target.getDimension();
}
void doSomething (double d) {
Iterator <? extends Interpolatable> it = target.getIterator(d);
Interpolatable t = it.next();
…
}
}
Basically, you are never passing any instance of the interface to the class. You are just using calls to the type (class), v.g. T.getDimension();
Also you do not need generics at all for this. Plain old interfaces work the way that you want.
You can just do:
class Interpolator {
Interpolable interpolable = null;
Interpolator (Interpolable _interpolable) {
this.interpolable = _interpolable;
}
void doSomething (double d) {
Iterator<Interpolable> it = this.interpolable.getIterator(d);
Interpolatable t = it.next();
…
}
}
I recommend that before getting into generics you work more used to interface, static/instance methods and other more basic stuff...
cant you say class Interpolator extends Coordinate
and then just call the method straight away...
I think you're simply overusing generics. This should work:
class Interpolator {
Interpolatable myInterpolatable;
Interpolator (Interpolatable i) {
myInterpolatable = i;
int dim = i.getDimension();
}
void doSomething (double d) {
Iterator <Interpolatable> it = myInterpolatable.getIterator(d);
Interpolatable t = it.next();
…
}
}
精彩评论