2009-07-05 6 views
42

nota rapida: esempi dal tutorial Scala for Java Refugees Part 5: Traits and Types.miscelazione più tratti in Scala

Supponiamo di avere i tratti Studente, Lavoratore, Sottopagato e Giovane.

Come si può dichiarare una classe (non istanza), CollegeStudent, con tutti questi tratti?

Nota: Sono consapevole dei casi simplests, come CollegeStudent con uno o due tratti:

class CollegeStudent extends Student with Worker 
+1

??? fare una domanda e poi essersi autoproclamata –

+0

L'avevo provato una volta con Eclipse molto tempo fa e questo non ha funzionato. Dopo l'aggiornamento, e scrivendo il test ho pensato: "Forse proverò qualcosa e vedrò se riesco a trovarlo da solo". –

+14

@Peter: non c'è niente di sbagliato nel chiedere e rispondere, purché sia ​​una domanda valida. – Grundlefleck

risposta

86

E 'facile, quando si dichiara una classe basta usare il "con" parola chiave più spesso come si desidera

class CollegeStudent extends Student with Worker with Underpaid with Young 

l'ordine dei tratti può essere importante se un tratto sta cambiando il comportamento della classe, tutto dipende da tratti che si sta utilizzando.

Anche se non si vuole avere una classe che usa sempre gli stessi tratti è possibile usarle in seguito:

class CollegeStudent extends Student 
new CollegeStudent with Worker with Underpaid with NotSoYoungAnymore 
+1

Cambiare il comportamento significa chiamare un metodo tratto implementato e con lo stesso nome in più tratti. Quindi, basato sull'ordine delle caratteristiche, chiamerà quel metodo. –

7

Penso che sia molto importante per spiegare non solo la sintassi, ma anche quale ruolo svolge l'ordinamento dei tratti. Ho trovato la spiegazione in Jason Swartz Learning Scala (pagina 177) abbastanza illuminante.

  • Una classe Scala può estendere più tratti contemporaneamente, ma le classi JVM possono estendere solo una classe genitore. Il compilatore Scala risolve questo creando "copie di ciascun tratto per formare una gerarchia a colonna singola alta della classe e tratti", un processo noto come linearizzazione .

  • In questo contesto, si estende più tratti in comune con i nomi dei campi identici non riuscirebbe a compilare, esattamente lo stesso "come se si stesse estendendo una classe e che fornisce la propria versione di un metodo ma non è riuscito ad aggiungere un parola chiave override" .

  • E dal momento che determina la forma dell'albero di ereditarietà, l'ordine di linearizzazione è davvero una questione molto importante da considerare. Ad esempio, class D extends A with B with C (dove A è una classe e B e C sono tratti) diventerebbe class D extends C extends B extends A. I seguenti poche righe, anche dal libro, illustrare che perfettamente:

    trait Base { override def toString = "Base" } 
    class A extends Base { override def toString = "A->" + super.toString } 
    trait B extends Base { override def toString = "B->" + super.toString } 
    trait C extends Base { override def toString = "C->" + super.toString } 
    class D extends A with B with C { override def toString = "D->" + super.toString } 
    

    Una chiamata a new D() avrebbe il REPL stampare i seguenti:

    D->C->B->A->Base 
    

    che riflette perfettamente la struttura del grafico eredità linearizzato .