¿Alguien puede explicar los rasgos en Scala? ¿Cuáles son las ventajas de los rasgos sobre la extensión de una clase abstracta?
81
La respuesta corta es que puede usar múltiples rasgos, son "apilables". Además, los rasgos no pueden tener parámetros de constructor.
Así es como se apilan los rasgos. Tenga en cuenta que el orden de los rasgos es importante. Se llamarán de derecha a izquierda.
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
}
}
Este sitio ofrece un buen ejemplo del uso de rasgos. Una gran ventaja de los rasgos es que puede extender varios rasgos, pero solo una clase abstracta. Los rasgos resuelven muchos de los problemas con la herencia múltiple pero permiten la reutilización del código.
Si conoces ruby, los rasgos son similares a los mix-ins
fuente
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) { }
fuente
Este es el mejor ejemplo que he visto
Scala en la práctica: composición de rasgos - estilo Lego: http://gleichmann.wordpress.com/2009/10/21/scala-in-practice-composing-traits-lego-style/
class Shuttle extends Spacecraft with ControlCabin with PulseEngine{ val maxPulse = 10 def increaseSpeed = speedUp }
fuente
Los rasgos son útiles para mezclar funciones en una clase. Eche un vistazo a http://scalatest.org/ . Observe cómo puede mezclar varios lenguajes específicos de dominio (DSL) en una clase de prueba. mire la guía de inicio rápido para ver algunos de los DSL compatibles con Scalatest ( http://scalatest.org/quick_start )
fuente
De manera similar a las interfaces en Java, los rasgos se utilizan para definir tipos de objetos especificando la firma de los métodos compatibles.
A diferencia de Java, Scala permite que los rasgos se implementen parcialmente; es decir, es posible definir implementaciones predeterminadas para algunos métodos.
A diferencia de las clases, los rasgos pueden no tener parámetros de constructor. Los rasgos son como clases, pero que definen una interfaz de funciones y campos que las clases pueden proporcionar valores e implementaciones concretas.
Los rasgos pueden heredarse de otros rasgos o de clases.
fuente
Cito del sitio web del libro Programación en Scala, Primera Edición y más específicamente la sección llamada "¿ Tratar o no trazar? " Del Capítulo 12.
Hay un poco más de información en el enlace anterior sobre los rasgos y le sugiero que lea la sección completa. Espero que esto ayude.
fuente