Java 具有两种类型的自引用泛型
Java Self-referential generics with two types
假设我们有一个像这样的摘要 class:
abstract class Table<T extends Table<T, P>, P extends Menu<P>> { }
如何正确声明其实现?
public class TableImpl extends Table< **SOMETHING GOES HERE** > { }
我尝试了一些变体,我发现的唯一解决方法是创建额外的 classes:
public abstract class AbstractMenu extends Menu<AbstractMenu> { }
public abstract class AbstractTable extends Table<AbstractTable, AbstractMenu> { }
然后可以这样声明TableImpl:
public class TableImpl extends AbstractTable { }
编辑 1
根据 Ingo 的回答,现在看起来像这样:
public class MenuAndTableTest {
public abstract class Table<X extends Table<X>> {
public abstract <M extends Menu> M getParent();
public abstract X getThis();
}
public abstract class Menu<T extends Menu<T>> {
}
public class MenuImpl extends Menu<MenuImpl> {
}
public class TableImpl<M extends Menu> extends Table<TableImpl<M>> {
M parent;
public TableImpl(M parent) {
this.parent = parent;
}
@Override
public TableImpl getThis() {
return this;
}
@Override
public M getParent() {
return parent;
}
}
@Test
public void Test() {
// given
MenuImpl menuImpl = new MenuImpl();
// when
TableImpl<MenuImpl> tableImpl = new TableImpl<>(menuImpl);
// then
assertEquals(tableImpl, tableImpl.getThis());
assertEquals(menuImpl, tableImpl.getParent());
}
}
但现在 Table 实现中出现了一些额外的逻辑 - 不完全是我想要的。
如果您想要一个可以包含菜单的 table 的 table,为什么不将其声明为
class Table<X>
并用
实例化
Table<Table<Menu>>
假设我们有一个像这样的摘要 class:
abstract class Table<T extends Table<T, P>, P extends Menu<P>> { }
如何正确声明其实现?
public class TableImpl extends Table< **SOMETHING GOES HERE** > { }
我尝试了一些变体,我发现的唯一解决方法是创建额外的 classes:
public abstract class AbstractMenu extends Menu<AbstractMenu> { }
public abstract class AbstractTable extends Table<AbstractTable, AbstractMenu> { }
然后可以这样声明TableImpl:
public class TableImpl extends AbstractTable { }
编辑 1
根据 Ingo 的回答,现在看起来像这样:
public class MenuAndTableTest {
public abstract class Table<X extends Table<X>> {
public abstract <M extends Menu> M getParent();
public abstract X getThis();
}
public abstract class Menu<T extends Menu<T>> {
}
public class MenuImpl extends Menu<MenuImpl> {
}
public class TableImpl<M extends Menu> extends Table<TableImpl<M>> {
M parent;
public TableImpl(M parent) {
this.parent = parent;
}
@Override
public TableImpl getThis() {
return this;
}
@Override
public M getParent() {
return parent;
}
}
@Test
public void Test() {
// given
MenuImpl menuImpl = new MenuImpl();
// when
TableImpl<MenuImpl> tableImpl = new TableImpl<>(menuImpl);
// then
assertEquals(tableImpl, tableImpl.getThis());
assertEquals(menuImpl, tableImpl.getParent());
}
}
但现在 Table 实现中出现了一些额外的逻辑 - 不完全是我想要的。
如果您想要一个可以包含菜单的 table 的 table,为什么不将其声明为
class Table<X>
并用
实例化Table<Table<Menu>>