2013-03-25 4 views
9

in Java mit inneren Schnittstellen tun kompiliert ohne Fehler:Implementierung inneren Züge in Scala wie wir Dieser Code in Java

interface T { 
    interface Q { 
    } 
} 

class C implements T.Q { 
} 

während dieser Code in Scala nicht:

trait T { 
    trait Q { 
    } 
} 

class C extends T.Q { 
} 

Was die richtige ist Übersetzung (falls vorhanden) des Java-Codes in Scala?

Theoretische Erklärungen zum Sprachdesign sind willkommen.

+1

Zusätzlich zu dem, was andere bereits über pfadabhängigen Arten beantwortet, ist es auch erwähnenswert, dass Scala Notation für Java 'T.Q' ist' T # Q'. –

+0

Die 'T # Q'-Syntax, auf die sich Oleg bezieht, wird als [type projection] bezeichnet (http://stackoverflow.com/questions/6676048/why-does-one-select-scala-type-members-with-a-hash) - anstelle eines Punktes). Und beachte, dass du * Q * erweitern kannst, wenn du es innerhalb eines von T abgeleiteten Typs machst, z. 'Klasse A erweitert T {Klasse B erweitert Q}'. – AmigoNico

Antwort

10

Der inneren Typ Q definiert ist nur für bestimmte Instanz Umsetzung der T Eigenschaft zu verweisen erlauben würde. Da scala pfadabhängige Typen hat, hat jede Instanz von T ihr eigenes Subtrat 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] 

Wenn Sie eine Schnittstelle für ein generisches Verhalten benötigen für Ihre Kunden zu implementieren und nicht abhängig von einer bestimmten C Beispiel sollten Sie es innerhalb eines Object

definieren
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! 

Warum pfadabhängige Typen?

Was die Designgründen aussehen here

3

Sie können das nicht tun. Wenn Typen verschachtelt werden, erstellen Sie einen so genannten pfadabhängigen Typ, was bedeutet, dass der Typ jeder Instanz der inneren Entität an die spezifische Instanz gebunden ist, in der sie konstruiert ist.

Mit anderen Worten, ein Schnittstelle Sie Q keine unabhängige Existenz hat, dass Sie es abgesehen von einer Instanz von T.