我有很多接口(
Foo
和Bar
)、实现这些接口的抽象类(AbstractFoo
和AbstractBar
)以及扩展这些抽象类的类(FooImpl1
、FooImpl2
、BarImpl1
和) BarImpl2
)。接口是泛型的,参数相互指向。一切都在编译,直到我在 AbstractBar
类 (this.foo.addBar(this);
) 的构造函数中使用通用字段的方法。
class Main {
public static void main(String[] args) {}
interface Foo<B extends Bar> {
Set<B> getBars();
}
abstract class AbstractFoo<B extends AbstractBar> implements Foo<B> {
private final Set<B> bars = new HashSet<>();
public void addBar(B bar) {
this.bars.add(bar);
}
@Override
public Set<B> getBars() {
return this.bars;
}
}
class FooImpl1 extends AbstractFoo<BarImpl1> {}
class FooImpl2 extends AbstractFoo<BarImpl2> {}
interface Bar<F extends Foo> {
F getFoo();
}
abstract class AbstractBar<F extends AbstractFoo<?>> implements Bar<F> {
private final F foo;
public AbstractBar(F foo) {
this.foo = foo;
// this following line is breaking my head...
this.foo.addBar(this);
}
@Override
public F getFoo() {
return this.foo;
}
}
class BarImpl1 extends AbstractBar<FooImpl1> {
public BarImpl1(FooImpl1 foo) {
super(foo);
}
}
class BarImpl2 extends AbstractBar<FooImpl2> {
public BarImpl2(FooImpl2 foo) {
super(foo);
}
}
}
导入java.util.HashSet; 导入 java.util.Set;
类主要{ 公共静态无效主(字符串[]参数){}
interface Foo<B extends Bar<?>> {
Set<B> getBars();
}
abstract class AbstractFoo<B extends AbstractBar<? extends AbstractFoo<B>>> implements Foo<B> {
private final Set<B> bars = new HashSet<>();
public void addBar(B bar) {
this.bars.add(bar);
}
@Override
public Set<B> getBars() {
return this.bars;
}
}
class FooImpl1 extends AbstractFoo<BarImpl1> {}
class FooImpl2 extends AbstractFoo<BarImpl2> {}
interface Bar<F extends Foo<?>> {
F getFoo();
}
abstract class AbstractBar<F extends AbstractFoo<? extends AbstractBar<F>>> implements Bar<F> {
private final F foo;
public AbstractBar(F foo) {
this.foo = foo;
// This line should now compile correctly
this.foo.addBar(this);
}
@Override
public F getFoo() {
return this.foo;
}
}
class BarImpl1 extends AbstractBar<FooImpl1> {
public BarImpl1(FooImpl1 foo) {
super(foo);
}
}
class BarImpl2 extends AbstractBar<FooImpl2> {
public BarImpl2(FooImpl2 foo) {
super(foo);
}
}
}