2009-08-04 9 views

risposta

79

La risposta breve è che è possibile utilizzare più tratti: sono "impilabili". Inoltre, i tratti non possono avere parametri di costruzione.

Ecco come vengono impilati i tratti. Si noti che l'ordine dei tratti è importante. Si chiameranno da destra a sinistra.

class Ball { 
    def properties(): List[String] = List() 
    override def toString() = "It's a" + 
    properties.mkString(" ", ", ", " ") + 
    "ball" 
} 

trait Red extends Ball { 
    override def properties() = super.properties ::: List("red") 
} 

trait Shiny extends Ball { 
    override def properties() = super.properties ::: List("shiny") 
} 

object Balls { 
    def main(args: Array[String]) { 
    val myBall = new Ball with Shiny with Red 
    println(myBall) // It's a shiny, red ball 
    } 
} 
+3

La mancanza di parametri del costruttore è quasi completata utilizzando i parametri di tipo nei tratti. – Jus12

17

Questo site fornisce un buon esempio dell'uso dei tratti. Un grande vantaggio dei tratti è che puoi estendere più tratti ma solo una classe astratta. I tratti risolvono molti dei problemi con ereditarietà multipla ma consentono il riutilizzo del codice.

Se si conosce rubino, i tratti sono simili a mix-ins

3

I tratti sono utili per la miscelazione di funzionalità in una classe. Dai uno sguardo allo http://scalatest.org/. Nota come puoi mescolare in vari linguaggi specifici del dominio (DSL) in una classe di test. guarda la guida rapida per guardare alcune delle DSL supportate da Scalatest (http://scalatest.org/quick_start)

1

Analogamente alle interfacce in Java, i tratti vengono utilizzati per definire i tipi di oggetto specificando la firma dei metodi supportati.

A differenza di Java, Scala consente di implementare parzialmente i tratti; cioè è possibile definire implementazioni predefinite per alcuni metodi.

Al contrario delle classi, i caratteri potrebbero non avere parametri di costruzione. I tratti sono come le classi, ma che definiscono un'interfaccia di funzioni e campi che le classi possono fornire valori concreti e implementazioni.

I tratti possono ereditare da altri tratti o dalle classi.

4
package ground.learning.scala.traits 

/** 
* Created by Mohan on 31/08/2014. 
* 
* Stacks are layered one top of another, when moving from Left -> Right, 
* Right most will be at the top layer, and receives method call. 
*/ 
object TraitMain { 

    def main(args: Array[String]) { 
    val strangers: List[NoEmotion] = List(
     new Stranger("Ray") with NoEmotion, 
     new Stranger("Ray") with Bad, 
     new Stranger("Ray") with Good, 
     new Stranger("Ray") with Good with Bad, 
     new Stranger("Ray") with Bad with Good) 
    println(strangers.map(_.hi + "\n")) 
    } 
} 

trait NoEmotion { 
    def value: String 

    def hi = "I am " + value 
} 

trait Good extends NoEmotion { 
    override def hi = "I am " + value + ", It is a beautiful day!" 
} 

trait Bad extends NoEmotion { 
    override def hi = "I am " + value + ", It is a bad day!" 
} 

case class Stranger(value: String) { 
} 
 
Output : 

List(I am Ray 
, I am Ray, It is a bad day! 
, I am Ray, It is a beautiful day! 
, I am Ray, It is a bad day! 
, I am Ray, It is a beautiful day! 
) 

1

sto citando dal sito web del libro Programming a Scala, Prima edizione e più precisamente la sezione chiamata "To trait, or not to trait?" dal capitolo 12.

Ogni volta che si implementa un collezione di comportamento riutilizzabile, dovrai decidere se vuoi usare un tratto o una classe astratta. Non esiste una regola fissa, ma questa sezione contiene alcune linee guida da considerare.

Se il comportamento non verrà riutilizzato, renderlo un corso concreto. Dopo tutto, non è un comportamento riutilizzabile.

Se può essere riutilizzato in più classi non correlate, renderlo un tratto. Solo i tratti possono essere mescolati in diverse parti della gerarchia di classi.

C'è un po 'più di informazioni nel link sopra per quanto riguarda i tratti e suggerisco di leggere l'intera sezione. Spero che aiuti.