kmantel
kmantel

Reputation: 125

"Multi-level" generics, with subclassing and interfaces

The intention is to allow any two types of classes to be "matched," provided they follow an interface. That is, if a class U is matchable to V, it implements the following interface

public interface Matchable<U, V>

and can be matched with

public class Matcher<U extends Matchable<U, V>, V extends Matchable<V, U>>

For one case, I wanted to match two classes that have very similar properties, so I created a basic parent class for them to inherit from:

public abstract class MatchingPairItem<T> implements Matchable<? extends MatchingPairItem<T>, T>
public class ClassA extends MatchingPairItem<ClassB>
public class ClassB extends MatchingPairItem<ClassA>

But I am obviously missing something with the generic typing, receiving multiple errors, for example:

type argument ClassA is not within bounds of type-variable U
    Matcher<ClassA, ClassB> matcher = new Matcher<ClassA, ClassB>();
                                                                ^
where U,V are type-variables:
U extends Matchable<U,V> declared in class Matcher
V extends Matchable<V,U> declared in class Matcher

Can anyone point me in the right direction?

Upvotes: 3

Views: 429

Answers (1)

Mark Peters
Mark Peters

Reputation: 81074

With ? extends MatchingPairItem<T>, you're trying to model "the type parameter is the concrete type of the class". That's simply not something Java generics can model.

I think your best bet is to keep MatchingPairItem with two type parameters, one representing the "self" type:

abstract class MatchingPairItem<S, T> implements Matchable<S, T> {}
class ClassA extends MatchingPairItem<ClassA, ClassB> {}
class ClassB extends MatchingPairItem<ClassB, ClassA> {}

Of course, this might defeat some of the convenience you were looking for, but that's an unfortunate reality.

Upvotes: 2

Related Questions