【发布时间】:2015-08-01 18:56:14
【问题描述】:
我想继承泛型类和接口。有一个问题我无法理解。问题体现在下面的简化代码中:
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 在A1.java,F1 在F1.java。
我得到编译时错误:
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>)
我需要 A1 < ? extends F1< T>> 用于继承 F1 的类。
附加信息(编辑后):
我想要 2 个层次结构(“O”而不是“F”,“C”而不是“A”):
- 类的第一个层次结构(
O1、O2...)包含对象的所有相关信息以及“比较器”(分析一对相同类型的两个对象的任何函数)。对象的类定义了它接受的比较器的类型,主要要求是比较器应该接受托管对象类型的 2 个对象。例如,O1只能接受所有比较O1的比较器,O2可以有接受O2的比较器。 - 类的第二个层次是比较器(
C1、C2...)本身。他们比较层次结构 1 中的对象。
两个层次结构中的每个元素都添加了在子类中使用的补充功能。
让我们考虑以下用例,这是通过这些层次结构的路径之一:
-
O1有 2 个成员(不是类型!):val(任何类型),cmp(类型为C1,只接受O1)。 -
C1_1没有对应的对象O,但它实现了与集合相关的附加功能。它可以比较集合中的对象(“基本”类型,如int、String、TColor和“复杂”对象O)并应用仅返回 1 个值(例如最大值)的聚合器。 如果集合是基本类型,则使用cmp2来比较集合中的元素。对于集合中的复杂对象,使用它们的集成比较器。 -
C1_1_1实现了如何比较对象列表 (1:1)。C1_1_2(未显示)可用于比较对象集,例如与叉积。 -
O1_1具有TVALB类型的val,其中extend List<TVALA>和比较器C1_1_1。
C1_1_1/2 的其他子类可以有更精细的实现来比较基本对象和复杂对象。
支持代码:
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>
{
// ...
}
我使用依赖注入在特定类中分配比较器(C-tree 到对象O)。因此,这种方法(如果可行的话)可以灵活地为特定类型的对象选择合适的比较器。
【问题讨论】:
-
为了澄清,我们假设 F1 是特定“对象”的泛型类型,A1 是特定比较器的泛型类型,用于比较相同类型的 2 个特定对象。跨度>
-
鉴于过去一小时有 3 个答案,您可能应该更详细地说明您正在尝试做的事情 - 显然,您发现没有一个有用。
-
如果您使用比
A1和F1更具描述性的名称也会有所帮助。你在比较什么? -
@bcorso 我添加了更多细节。
-
我的回答哪里不足? (除了多态的东西,这本质上是不可避免的。)。请注意,泛型不是相互递归的,因此尚不清楚剩余的复杂性是什么......
标签: java generics inheritance