实现上界泛型方法
Implementing an Upper Bounded Generic Method
我在构建有点循环的通用配置时遇到了问题。我需要一个 "state" 接口,为通用 "container" 接口提供 getter。其方法上的容器接口需要接受通用 "state" 作为参数之一。我已经尝试了各种选项(真正的循环通用 class 参数,下面的各种变体),但我下面的是最接近我认为我需要的:
interface Container<K> {
<C extends Container<K>,S extends State<K,C>> C setData(K key, Object val,S state);
}
interface State<K,C extends Container<K>>{
C getContainer();
}
class BasicContainer<K> implements Container<K> {
public <C extends BasicContainer<K>, S extends State<K,C>> C setData(K key, Object val, S state) { return this;}
}
class BasicState<K> implements State<K,BasicContainer<K>> {
BasicContainer<K> container = new BasicContainer<K>();
public BasicContainer<K> getContainer(){
return container;
}
}
唉,编译器正在为 BasicContainer
方法提供著名的 methods have same erasure yet neither overrides the other
。我相信这是因为虽然 C extends BasicContainer<K>
是 C extends Container<K>
的子类型,但 S extends State<K,C>
是 而不是 Container<K>
中 S extends State<K,C>
的子类型=].
关于如何通过所需配置完成的任何建议?
更新
我将需要 Container
的其他实现,它们也需要与 State
实现一起工作,但 State
实现不会 return 这些实现。这是 class 上的循环参数失败的地方。
看起来 C
应该是 Container
接口上的类型参数,例如 K
。
一般来说,如果 Foo
是 Bar
的超类型,Bar
不能 向方法的泛型类型参数添加额外的约束Foo
。这只是遵循 Liskov 替换原则:任何 Bar
必须能够用于 anything a Foo
可以用于.
在BasicContainer.setData
的类型参数中约束C extends BasicContainer<K>
,当Container.setData
只有约束C extends Container<K>
时,具体违反了这个规则。
您可以做的是将 C
的上限作为 Container,
的类型参数,并在 BasicContainer
.
中将其设置为不同的值
这可能类似于以下之一:
interface Container<K, C extends Container<K, C>> {
<S extends State<K,C>> C setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }
...或者,如果您发现需要额外的泛型,
interface Container<K, C extends Container<K, C>> {
<C2 extends C, S extends State<K,C>> C2 setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }
(虽然说白了,第二个版本几乎肯定不是你想要的)
我在构建有点循环的通用配置时遇到了问题。我需要一个 "state" 接口,为通用 "container" 接口提供 getter。其方法上的容器接口需要接受通用 "state" 作为参数之一。我已经尝试了各种选项(真正的循环通用 class 参数,下面的各种变体),但我下面的是最接近我认为我需要的:
interface Container<K> {
<C extends Container<K>,S extends State<K,C>> C setData(K key, Object val,S state);
}
interface State<K,C extends Container<K>>{
C getContainer();
}
class BasicContainer<K> implements Container<K> {
public <C extends BasicContainer<K>, S extends State<K,C>> C setData(K key, Object val, S state) { return this;}
}
class BasicState<K> implements State<K,BasicContainer<K>> {
BasicContainer<K> container = new BasicContainer<K>();
public BasicContainer<K> getContainer(){
return container;
}
}
唉,编译器正在为 BasicContainer
方法提供著名的 methods have same erasure yet neither overrides the other
。我相信这是因为虽然 C extends BasicContainer<K>
是 C extends Container<K>
的子类型,但 S extends State<K,C>
是 而不是 Container<K>
中 S extends State<K,C>
的子类型=].
关于如何通过所需配置完成的任何建议?
更新
我将需要 Container
的其他实现,它们也需要与 State
实现一起工作,但 State
实现不会 return 这些实现。这是 class 上的循环参数失败的地方。
看起来 C
应该是 Container
接口上的类型参数,例如 K
。
一般来说,如果 Foo
是 Bar
的超类型,Bar
不能 向方法的泛型类型参数添加额外的约束Foo
。这只是遵循 Liskov 替换原则:任何 Bar
必须能够用于 anything a Foo
可以用于.
在BasicContainer.setData
的类型参数中约束C extends BasicContainer<K>
,当Container.setData
只有约束C extends Container<K>
时,具体违反了这个规则。
您可以做的是将 C
的上限作为 Container,
的类型参数,并在 BasicContainer
.
这可能类似于以下之一:
interface Container<K, C extends Container<K, C>> {
<S extends State<K,C>> C setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }
...或者,如果您发现需要额外的泛型,
interface Container<K, C extends Container<K, C>> {
<C2 extends C, S extends State<K,C>> C2 setData(K key, Object val,S state);
}
class BasicContainer<K> implements Container<K, BasicContainer<K>> { ... }
(虽然说白了,第二个版本几乎肯定不是你想要的)