I would like to have an inheritance of generic classes and interfaces. There is one issue I cannot understand. The problem is reflected in the following simplified code:
public interface A1 <T extends F1<?>> {
public void compare(T f1, T f2);
}
public class F1 < T extends A1<? extends F1<T>> >
{
T a;
public void compare(F1<T> f) {
a.compare(this, f);
}
}
A1
is in A1.java
, F1
is in F1.java
.
I get the compile-time error:
The method compare(capture#1-of ? extends F1<T>, capture#1-of ? extends F1<T>)
in the type A1<capture#1-of ? extends F1<T>> is not applicable for the
arguments (F1<T>, F1<T>)
I need A1 < ? extends F1< T>>
for classes subclassing F1
.
Additional information (after editing):
I would like to have 2 hierarchies ("O" instead of "F", "C" instead of "A"):
- The first hierarchy of classes (
O1
,O2
...) contains all relevant information of the object as well as the "comparator" (any function which analyses a pair of 2 objects of the same type). The class of the object defines the type of the comparator which it accepts, and the main requirement is that the comparator should accept 2 object of the type of the hosting object. For example,O1
can only accept all the comparators which compareO1
's,O2
can have comparators that acceptO2
's. - The second hierarchy of classes is comparators (
C1
,C2
...) themselves. they compare objects from the hierarchy 1.
Each element in both hierarchies adds supplementary functionality which is leveraged in subclasses.
Let's consider the following use case, one of the paths through these hierarchies:
O1
has 2 members (not types!):val
(any type),cmp
(of typeC1
which only acceptsO1
).C1_1
does not have a corresponding objectO
, but it implements additional functionality related to collections. It can compare objects ("basic" types likeint
,String
,TColor
and "complex" objectsO
's) in the collection and apply the aggregator which returns only 1 value (e.g. maximum). If the collection is of basic types,cmp2
is utilized to compare elements within the collection. For complex objects in collections, their integrated comparators are utilized.C1_1_1
implements how to compare lists of objects (1:1).C1_1_2
(not presented) can be used to compare sets of objects, e.g. with the cross product.O1_1
hasval
of the typeTVALB
whichextend List<TVALA>
and the comparatorC1_1_1
.
Other subclasses of C1_1_1/2
can have more refined implementations for comparing basic and complex objects.
The supporting code:
public abstract class O1 <TVAL, TC extends C1<? extends O1<TVAL>>>
{
TVAL val;
TC cmp;
public double compare(O1<TVAL, TC> o) {
return cmp.compare(this, o);
}
}
public interface C1 <TO extends O1<?, ?> > {
public double compare(TO t1, TO t2) {
// ...
}
}
public abstract class C1_1 <
TVALA,
TVALB extends Collection<TVALA>,
TO extends O1<TVALB, ?>
>
extends C1 <TO> {
Cmp2<TVALA, Double> cmp2;
IAggregator<TVALA> aggr;
Double compare(TO o1, TO o2) {
return aggr.apply(
compPairs(o1.val, o2.val, cmp2)
);
}
abstract pairs<TVALA> compPairs(
TVALB b1
, TVALB b2
, Cmp2<TVALA> cmp2);
// aggregation
public static class Aggr1<TVALA> implements IAggregator<TVALA> {
public Double apply(pairs<TVALA> pairs) {
//...
}
}
public static class Aggr2<TVALA> implements IAggregator<TVALA> {
// ...
}
}
public abstract class C1_1_1 <
TVALA,
TVALB extends List<TVALA>,
TO extends O1<TVALB, ?>
>
extends C1_1 <TO> {
pairs<TVALA> compPairs(
TVALB b1
, TVALB b2
, Cmp2<TVALA> cmp2) {
// ...
}
}
public abstract class O1_1 <
TVALA extends O1<?,?>,
TVALB extends List<TVALA>
, TC extends C1_1_1<TVALA, TVALB, ? extends O1_1<TVALA, TVALB, TC>>>
extends O1<TVAL>
{
// ...
}
I use dependency injection to assign comparators (C
-tree to objects O
) in the specific class. Therefore, this approach (if it is feasible) can give the possibility to have a flexibility in choosing the proper comparator for specific types of objects.