AMendenhall
02-07-2016, 00:51
Consider the following case:
You want to make an interface which forces the functionality of being interpolable, that is, being able to be interpolated. You'd probably start off with the following code
public interface Interpolable {
/**
* Interpolates this value and @param a
*/
public Interpolable interpolate(Interpolable a);
}
Herein lies the 1st problem:
If the interpolate method accepts a, of type Interpolable, and returns some Interpolable, then any implementing class could accept and return any other implementing class. Desired functionality would limit both of these to only the type of the class which is doing the implementing.
My solution:
public interface Interpolable<T extends Interpolable<T>> {
/**
* Interpolates this value and @param a
*/
public T interpolate(T a);
}
This way, any class which implements interpolable must specify that the generic type T is itself, that is, the method interpolate accepts and returns only itself. Problem is, an imposter class could lie and say that it accepts and returns a different interpolable type. Is there a more elegant way to do this?
Say you also want your Interpolable interface extend UnaryOperator, because it takes in an Object and returns an Object, both of which are of type T. However, the method required by UnaryOperator is T apply(T a). A way to get around that would be to make Interpolable an abstract class and make the method interpolate call apply. Are there more elegant ways to do this?
public abstract class Interpolable<T extends Interpolable<T>> implements UnaryOperator<T> {
/**
* Interpolates this value and @param a
*/
public T interpolate(T a) {
return apply(a);
}
}
I know this isn't super FRC oreinted, but I'm still using it for some cool robotics stuff that I think I'll release sometime this summer. Thanks for any replies.
You want to make an interface which forces the functionality of being interpolable, that is, being able to be interpolated. You'd probably start off with the following code
public interface Interpolable {
/**
* Interpolates this value and @param a
*/
public Interpolable interpolate(Interpolable a);
}
Herein lies the 1st problem:
If the interpolate method accepts a, of type Interpolable, and returns some Interpolable, then any implementing class could accept and return any other implementing class. Desired functionality would limit both of these to only the type of the class which is doing the implementing.
My solution:
public interface Interpolable<T extends Interpolable<T>> {
/**
* Interpolates this value and @param a
*/
public T interpolate(T a);
}
This way, any class which implements interpolable must specify that the generic type T is itself, that is, the method interpolate accepts and returns only itself. Problem is, an imposter class could lie and say that it accepts and returns a different interpolable type. Is there a more elegant way to do this?
Say you also want your Interpolable interface extend UnaryOperator, because it takes in an Object and returns an Object, both of which are of type T. However, the method required by UnaryOperator is T apply(T a). A way to get around that would be to make Interpolable an abstract class and make the method interpolate call apply. Are there more elegant ways to do this?
public abstract class Interpolable<T extends Interpolable<T>> implements UnaryOperator<T> {
/**
* Interpolates this value and @param a
*/
public T interpolate(T a) {
return apply(a);
}
}
I know this isn't super FRC oreinted, but I'm still using it for some cool robotics stuff that I think I'll release sometime this summer. Thanks for any replies.