2013-03-25 83 views
9

内部接口这段代码在Java的编译没有错误:实现内性状斯卡拉像我们一样在Java

interface T { 
    interface Q { 
    } 
} 

class C implements T.Q { 
} 

,而这些代码的Scala没有:

trait T { 
    trait Q { 
    } 
} 

class C extends T.Q { 
} 

什么是正确的将Java代码列表翻译(如果存在)到Scala中?

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

+1

除了别人已经回答了路径依赖的类型,这也是值得注意的是,Scala的符号来表示Java的'T.Q'是'T#Q'。 – 2013-03-25 14:48:19

+0

Oleg提到的'T#Q'语法被称为[type projection](http://stackoverflow.com/questions/6676048/why-does-one-select-scala-type-members-with-a-hash -instead对的一点)。并且请注意,如果你在从T派生的类型中进行扩展,你可以*扩展Q,例如, 'A类扩展T {B类扩展Q}'。 – AmigoNico 2013-03-27 01:23:58

回答

10

的一个实例的内型Q仅针对特定实例实施T性状的定义分开参考。由于scala具有路径相关的类型,因此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 = [email protected] 


scala> val c = new C 
c: C = [email protected] 

scala> new c.Q {} 
res4: c.Q = [email protected] 

如果你需要一个通用的行为为您的客户来实现,而不是依赖于特定的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 = [email protected] 

scala> inT.implementMe 
implemented! 

定义它

为什么路径依赖类型?

至于设计方面的原因,看看here

3

你不能那样做。当嵌套类型时,您将创建称为路径依赖类型,这意味着内部实体的每个实例的类型都与其构建的特定实例绑定在一起。

换句话说,你接口Q具有没有独立存在,将允许用户从T.