【问题标题】:Implementing inner traits in Scala like we do with inner interfaces in Java在 Scala 中实现内部特征,就像我们在 Java 中使用内部接口一样
【发布时间】:2013-03-14 22:28:58
【问题描述】:

Java 中的这段代码编译没有错误:

interface T {
    interface Q {
    }
}

class C implements T.Q {
}

而 Scala 中的这段代码没有:

trait T {
    trait Q {
    }
}

class C extends T.Q {
}

Java 代码清单到 Scala 的正确翻译(如果存在)是什么?

欢迎提供有关语言设计的理论解释。

【问题讨论】:

  • 除了其他人已经回答的关于路径依赖类型的问题外,还值得注意的是,Scala 对 Java 的T.Q 表示法是T#Q
  • Oleg 提到的T#Q 语法称为type projection。请注意,如果您在从 T 派生的类型中执行此操作,则 可以 扩展 Q,例如class A extends T { class B extends Q }.

标签: java scala inner-classes


【解决方案1】:

内部类型 Q 仅为 T 特征的特定实例实现定义。由于 scala 有 path-dependent 类型,T 的每个实例都有自己的子特征 Q

scala> trait T {
     |   trait Q
     | }
defined trait T

scala> class C extends T {
     |   def getQ: this.Q = new this.Q {}
     | }
defined class C

scala> val inC = (new C).getQ
inC: C#Q = C$$anon$1@3f53073a


scala> val c = new C
c: C = C@1a7e4ff0

scala> new c.Q {}
res4: c.Q = $anon$1@36bbb2f5

如果您需要一个接口来为您的客户端实现一个通用行为,并且不依赖于特定的C 实例,您应该在Object 中定义它

scala> object T {
     |   trait Q {
     |     def implementMe: Unit
     |   }
     | }
defined module T

scala> val inT = new T.Q {
     |   def implementMe = println("implemented!")
     | }
inT: T.Q = $anon$1@20f2a08b

scala> inT.implementMe
implemented!

为什么是路径依赖类型?

至于设计原因看here

【讨论】:

    【解决方案2】:

    你不能那样做。嵌套类型时,您将创建所谓的路径依赖类型,这意味着内部实体的每个实例的类型都与构造它的特定实例相关联。

    换句话说,你的接口 Q 没有独立的存在,可以让你在 T 的实例之外引用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-12
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 2014-03-06
      • 2013-08-15
      • 2020-08-27
      相关资源
      最近更新 更多