3

我有两个特征,一个扩展另一个,每个都有一个内部类,一个扩展另一个,具有相同的名称:

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
}

如何访问A.X班级正文中的C班级?重命名B.X不隐藏A.X不是首选方式。

为了让事情变得有点复杂,在我遇到这个问题的情况下,特征具有类型参数(本示例中未显示)。

4

2 回答 2

16
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
于 2010-03-13T00:06:35.337 回答
1

对于那些对这个奇异问题感兴趣的人,我发现它也可以作为函数的返回值。由于我的特征 A 和 B 具有类型参数,它应该导致更简洁的代码:

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
于 2010-03-13T07:04:43.137 回答