我最近一直在试验泛型,并找到了一个可以使用它们的好例子,但是,我陷入了困境,我的搜索没有找到解决方案,或者我误解了。请参阅以下代码示例:
open class X()
class Y : X()
class Z : X()
abstract class A<T : X> {
lateinit var one: T
fun setup(
one: T
) {
this.one = one
}
}
class B<T : Y> : A<T>()
class C {
fun initB() {
B<Y>() // Works as intended
B<Z>() // Type argument is not within its bounds
B<X>() // Type argument is not within its bounds
}
}
我想要一种情况,即从 one
类型的 class B
访问 one
是正确推断的,所以如果我实例化 B
类型为 Z
那么 one
也将被推断为类型 Z
。不幸的是,按照我认为正确的方式执行此操作会导致“Type argument is not within its bounds
”。任何帮助将不胜感激。
答案 0 :(得分:4)
B 的类型必须是您定义的 Y 的子类型 B<T : Y>
,但 X 和 Z 都不是 Y 的子类型。X 是 Y 的超类型,而 Z 与 Y 根本没有垂直联系.
即使它们是亚型,你也不能做你希望做的事。由于您的类有一个 T
变量,因此 T
必须保持不变才能工作。不变意味着您不能隐式地向上和向下转换类的实例的类型。
考虑一下如果它允许你它会如何崩溃:
val bY: B<Y> = B<Y>()
val bX: B<X> = bY // not allowed because of invariance
// If it were allowed:
bX.one = X()
val y: Y = bY.one // ClassCastException: cannot cast X to Y