考虑这个(有点人为的)例子:
abstract class Obj[A, B] {
def id: Long
def parent: B
}
abstract class TopLevel[A] extends Obj[A, A] {
def parent: A = this.asInstanceOf[A] // How terrible is this?
}
abstract class AbsChild[A, B] extends Obj[A, B] {
def parent: B
}
case class Top(id: Long) extends TopLevel[Top]
case class Child(id: Long, parent: Top) extends AbsChild[Child, Top]
Run Code Online (Sandbox Code Playgroud)
为了描绘更好的图片,想象一下AbsChild文件系统上的某种目录,以及TopLevel它AbsChild所属的物理驱动器.所以parent实际上并不是指对象的直接父级(比如包含它的目录),而是引用树中的顶级对象.
在某些应用程序中,我将要处理a List[Obj[A, B]],而不是立即知道它是什么Obj.在这种情况下,即使a TopLevel拥有a 也会很好parent,它应该只返回对自身的引用.这就是我的问题.
定义def parent: A = this为TopLevel不工作:
<console>:14: error: type mismatch;
found : TopLevel.this.type (with underlying type TopLevel[A])
required: A
Run Code Online (Sandbox Code Playgroud)
但def parent: A = this.asInstanceOf[A]确实,并且似乎在实践中正确运作.
scala> val top = Top(1)
top: Top = Top(1)
scala> val child = Child(1, top)
child: Child = Child(1,Top(1))
scala> top.parent
res0: Top = Top(1)
scala> child.parent
res1: Top = Top(1)
Run Code Online (Sandbox Code Playgroud)
但这真的没问题吗?使用asInstanceOf[A]感觉非常脏,并让我想知道它是否会以某种方式失败ClassCastException.
ClassCastException如果你有一个TopLevel[A]不是的子类,你会得到一个A.为了避免需要施放你应该使用自我类型(我不确定这是否是正确的名称):
abstract class TopLevel[A] extends Obj[A, A] {
this: A =>
def parent: A = this
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |