2

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 defined 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.)

2
  • 1
    None of your code uses the static keyword - can you check you have posted your code correctly? Commented Aug 10, 2011 at 10:57
  • @Bohemian He is using the method .getIterator or .getDimension from the type(class) itself (v.g., T.getDimension()), not from an instance. Commented Aug 10, 2011 at 11:02

4 Answers 4

4

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();
    …
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

+1 IMHO this approach is the simplest and cleanest - it only requires an extra parameter in the constructor and this can be hidden with a non-public constructor so clean API. Other approaches require dummy instance parameters in methods... yuk.
4

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...

Comments

0

cant you say class Interpolator extends Coordinate

and then just call the method straight away...

1 Comment

No, because another time, I want to interpolate something else than a Coordinate.
0

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();
    …
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.