A common pattern in object oriented programming is interfacing classes that have the same methods. If these classes encapsulate a datatype and expose methods that take the datatype as a parameter, generic interfaces. The approach results in the ability to apply a generic algorithm on different encapsulated data types.

For example vector math classes have this property, they can be defined for `double`

and `float`

datatypes and also for 2- and 3-dimensional implementations with methods for doing common operations.

public final class Vec3 implements Vec<Vec3> { private double x; private double y; private double z; /** * returns the distance to another vector * @param other the other vector * @return distance */ public final double distance(Vec3 other) { return Math.sqrt( (x-other.x)*(x-other.x)+ (y-other.y)*(y-other.y)+ (z-other.z)*(z-other.z)); } } public final class Vec2 implements Vec<Vec2> { private double x; private double y; /** * returns the distance to another vector * @param other the other vector * @return distance */ public final double distance(Vec2 other) { return Math.sqrt( (x-other.x)*(x-other.x)+ (y-other.y)*(y-other.y)); } }

The generic interface that both classes implement can then be declared like this:

public interface Vec<V> { double distance(V other); }

It can contain all functions that have the same ‘abstract’ method signature that the classes have in common, ie. the more complicated cross product that returns a vector again.

The real benefit of this is not immediately obvious, consider adding up the distances of a list of items – one would naively just implement the method for each vector type Vec2 and Vec3. This results in duplicate code, reduced maintainability and is errorprone.

A class holding the algorithms operating on the Vec<V> interface can be used instead, the method needs to make use of the disance(V) method to determine the overall distance.

public class Toolbox { /** * Determines the overall distance between the points in the list */ public static <T extends Vec<T>> double getAllDistances(List<T> points) { T prevPoint = points.get(0); T point; double sum = 0.0; int len = points.size(); for (int i=1;i<len; i++) { point = points.get(i); sum+=point.distance(prevPoint); prevPoint = point; } return sum; } }

This method is type-safe and works with all types implementing the generic Vec interface due to the `<T extends Vec<T>>`

declaration. That way algorithms on vectors can safely be defined once for several variations of the classes.

In contrast, a declaration like below seems more natural at first, but does not work:

public static <T> double getAllDistances(List<Vec<T>> points) { Vec<T> prevPoint = points.get(0); Vec<T> point; double sum = 0.0; for (int i=1; i<points.size(); i++) { point = points.get(i); sum+=point.distance(prevPoint); prevPoint = point; } return sum; }

Here, calling the method `point.distance(prevPoint)`

gives a compiler error since prevPoint is of type `Vec<T>`

but the method signature is `distance(V other)`

and expects it to be `T`

, rather than `Vec<T>`

.