Is there something wrong with asInstanceOf in this example using generics?
Consider this (somewhat contrived) example:
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]
To paint the best picture, think of it AbsChild
as a kind of directory on the file system and TopLevel
as the physical disk to which it belongs AbsChild
. So it parent
doesn't really refer to the direct parent object (like the directory that contains it), but rather a reference to the top-level object in the tree.
In some applications I will deal with List[Obj[A, B]]
where it is not immediately known what it is Obj
. In this case, it would be nice if it even TopLevel
had an a parent
that should just return a reference to itself. And that is my question.
Definition def parent: A = this
for TopLevel
doesn't work:
<console>:14: error: type mismatch;
found : TopLevel.this.type (with underlying type TopLevel[A])
required: A
But def parent: A = this.asInstanceOf[A]
does and seems to work correctly in practice.
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)
But is it really good? The use asInstanceOf[A]
feels incredibly messy and leaves me wondering if it won't work with ClassCastException
.
source to share