鉴于这些类和变量:
abstract class Base[T <: Base[_]] {
val self: T
def me(): T = self
}
class Derived extends Base[Derived] {
lazy val self = this
def whoAmI() = "Im derived"
}
val d = new Derived
我可以安全地拨打d.foo().whoAmI()
但这也是类型安全吗?
abstract class Base[T <: Base[_]] {
def me(): T = this.asInstanceOf[T]
}
class Derived extends Base[Derived] {
def whoAmI() = "Im derived"
}
我正在考虑边缘情况,其中其他类从Derived扩展而且强制转换可能会爆炸
答案 0 :(得分:4)
它不是类型安全的。如果您发现需要使用asInstanceOf
进行编译,那么答案绝对是“不”。如果只有一个子类型,唯一一次“安全”转换为子类型。否则,你无法做出任何保证。
考虑这个例子:
abstract class Base[T <: Base[_]] {
def me(): T = this.asInstanceOf[T]
}
class A extends Base[A]
class B extends Base[A]
scala> val b = new B
b: B = B@4b44655e
scala> b.me
java.lang.ClassCastException: B cannot be cast to A
... 33 elided
我们扩展的T
中的Base
必须与我们正在创建的子类型相同,只是它们都扩展Base
没有限制。 A
和B
都是Base[_]
,但B
不是A
,因此投放到A
会不安全。
这很容易通过在Base
中引入自我类型来解决,这需要它也是T
。然后,我们可以确定this
是T
并且不需要投射。
abstract class Base[T <: Base[_]] { this: T =>
def me(): T = this
}
这将不再编译:
scala> class B extends Base[A]
<console>:12: error: illegal inheritance;
self-type B does not conform to Base[A]'s selftype A
class B extends Base[A]
^