2013-03-25 60 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.