¿Cómo acceder a la clase interna "anulada" en Scala?
-
19-09-2019 - |
Pregunta
Tengo dos rasgos, uno que extiende al otro, cada uno con una clase interna, uno que extiende al otro, con los mismos nombres:
trait A {
class X {
def x() = doSomething()
}
}
trait B extends A {
class X extends super.X {
override def x() = doSomethingElse()
}
}
class C extends B {
val x = new X() // here B.X is instantiated
val y = new A.X() // does not compile
val z = new A.this.X() // does not compile
}
¿Cómo accedo? A.X
clase en el C
el cuerpo de la clase?Cambiar el nombre B.X
no esconderse A.X
no es una forma preferida.
Para complicar un poco las cosas, en la situación en la que encontré este problema, los rasgos tienen parámetros de tipo (no se muestran en este ejemplo).
Solución
trait A {
class X {
def x() = "A.X"
}
}
trait B extends A {
class X extends super.X {
override def x() = "B.X"
}
}
class C extends B {
val self = this:A
val x = new this.X()
val y = new self.X()
}
scala> val c = new C
c: C = C@1ef4b
scala> c.x.x
res0: java.lang.String = B.X
scala> c.y.x
res1: java.lang.String = A.X
Otros consejos
Para aquellos interesados en este tema exótico, he descubierto que también funciona como valor de retorno de una función.Dado que mis rasgos A y B tienen parámetros de tipo, debería conducir a un código más conciso:
trait A[T, U, V] {
class X {
def x() = "A.X"
}
def a = this:A[T, U, V]
}
trait B[T, U, V] extends A[T, U, V] {
class X extends super.X {
override def x() = "B.X"
}
}
class C extends B[SomeClass, SomeOtherClass, ThirdOne] {
val aVerbose = this:A[SomeClass, SomeOtherClass, ThirdOne] // works but is a bit ugly
val aConcise = a
val x = new this.X()
val y = new aVerbose.X()
val z = new aConcise.X()
}
scala> val c = new C()
c: C = C@1e852be
scala> c.x.x()
res2: java.lang.String = B.X
scala> c.y.x()
res3: java.lang.String = A.X
scala> c.z.x()
res4: java.lang.String = A.X
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow