我正在尝试实现一个关于它的项目的通用容器。所有可能的项类共享一个抽象基类,该基类提供对周围容器的访问。
以下代码显示了我最简单的方法:
public class GenericContainerProblem {
public static void main(String[] args) {
Container<SpecificItem> container = new Container<>();
new SpecificItem(container);
}
private static class Container<ItemType extends AbstractItem> {
private final List<ItemType> list = new ArrayList<>();
public Container() {
//
}
protected void addItem(ItemType specificItem) {
list.add(specificItem);
}
}
private static abstract class AbstractItem {
protected final Container<? extends AbstractItem> container;
public AbstractItem(Container<? extends AbstractItem> container) {
this.container = container;
container.addItem(this); // fails *
}
}
private static class SpecificItem extends AbstractItem {
public SpecificItem(Container<SpecificItem> container) {
super(container);
container.addItem(this); // succeeds
}
}
}
*)错误:The method addItem(capture#3-of ? extends GenericContainer.AbstractItem) in the type GenericContainer.Container<capture#3-of ? extends GenericContainer.AbstractItem> is not applicable for the arguments (GenericContainer.AbstractItem)
由于声明? extends AbstractItem
允许的类型不匹配,因此无法正常工作。我想我需要一些类型约束来告诉编译器Container<?>
- AbstractItem
中使用的this
类型对AbstractItem
有效。
如何以能够访问特定子类的通用容器的方式声明/调用function render() {
var delta = Math.random() * (0.02 + 0.02) + speed;
cubeGroup.rotation.x -= cubeGroup.rotation.x+delta;
cubeGroup.rotation.y += delta + 0.02;
cubeGroup.rotation.z -= 0.02;
textGroup.rotation.x -= textGroup.rotation.x+delta;
textGroup.rotation.y -= delta + 0.02;
textGroup.rotation.z += 0.02;
renderer.render(scene, camera);
}
- 类(及其构造函数)?
答案 0 :(得分:1)
据我所知,您需要使AbstractItem通用,以指定它使用的容器的类型。您还需要在AbstractItem构造函数中使用未经检查的强制转换。
但是你真的确定你想要容器和容器之间的这种双向关联吗?也许你应该重新考虑这个设计。
public class GenericContainerProblem {
public static void main(String[] args) {
Container<SpecificItem> container = new Container<>();
new SpecificItem(container);
}
private static class Container<ItemType extends AbstractItem<ItemType>> {
private final List<ItemType> list = new ArrayList<>();
public Container() {
//
}
protected void addItem(ItemType specificItem) {
list.add(specificItem);
}
}
private static abstract class AbstractItem<T extends AbstractItem<T>> {
protected final Container<T> container;
public AbstractItem(Container<T> container) {
this.container = container;
container.addItem((T) this);
}
}
private static class SpecificItem extends AbstractItem<SpecificItem> {
public SpecificItem(Container<SpecificItem> container) {
super(container);
container.addItem(this);
}
}
}