简单协方差示例:为什么asInstance有效?
class Fruit(name: String) { def get_name = name}
class Apple(name: String) extends Fruit(name)
class Orange(name: String) extends Fruit(name)
class BigOrange(name:String) extends Orange(name)
// Contrived but simple covariant box with some utility functions
class Box[+T <: Fruit] {
def foo[ U >: T] (item: U): String = item.asInstanceOf[T].get_name
}
val f = new Fruit("fruit")
val a = new Apple("apple")
val o = new Orange("orange")
// Error. Makes sense apples cannot be casted to oranges
println( a.asInstanceOf[Orange])
val bo1 = new Box[Orange]
println(bo1.foo(a)) // Returns Apple ! How was an apple seemingly casted to an orange?
那为什么最后一行有效呢?是不是要求将传递的苹果变成橙色的逻辑?
第二个问题:为什么这段代码会给我get_name not not error?
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[ U >: T] (item: U): String = item.get_name
}
在[+ T&lt ;: Fruit]和U&gt;:T之间,是不是很明显该项应该有一个get_name?为什么错误?
答案 0 :(得分:1)
asInstanceOf[T]
实际上什么都不做,因为T
的{{1}}类型已被删除。您还应该收到编译器的警告。
答案 1 :(得分:1)
这里的问题......
class Box[+T <: Fruit] (item: T) {
val contents = item
def foo[U >: T] (item: U): String = item.get_name
}
...是你用另一个item
遮蔽了一个item: T
。第1个get_name
, 有一个item: U
成员,编译器可以识别,但第二个Fruit
没有。它可以是get_name
的父类或超类,这意味着无法保证'
成员。
答案 2 :(得分:1)
在[+ T&lt ;: Fruit]和U&gt;:T之间,是不是很明显该项应该有一个get_name?
当然不是。例如,U = Any
满足约束条件且没有get_name
成员。