Pregunta

¿Alguien puede explicar los rasgos en Scala? ¿Cuáles son las ventajas de los rasgos sobre la extensión de una clase abstracta?

¿Fue útil?

Solución

La respuesta corta es que puedes 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 son importantes. 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
  }
}

Otros consejos

Este sitio ofrece un buen ejemplo de uso de rasgos. Una gran ventaja de los rasgos es que puede extender múltiples rasgos pero solo una clase abstracta. Los rasgos resuelven muchos de los problemas con herencia múltiple pero permiten la reutilización de código.

Si conoce Ruby, los rasgos son similares a los mix-ins

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

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
    }

Los rasgos son útiles para mezclar la funcionalidad en una clase. Eche un vistazo a http://scalatest.org/ . Observe cómo puede mezclar varios idiomas específicos de dominio (DSL) en una clase de prueba. mire la guía de inicio rápido para ver algunos de los DSL admitidos por Scalatest ( http://scalatest.org/quick_start)

Similar a las interfaces en Java, los rasgos se utilizan para definir tipos de objetos al especificar la firma de los métodos admitidos.

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 las clases, pero que definen una interfaz de funciones y campos que las clases pueden proporcionar valores e implementaciones concretas.

Los rasgos pueden heredar de otros rasgos o de clases.

Cito del sitio web del libro Programación en Scala, Primera edición y más específicamente la sección llamada " ¿Rasgo, o no rasgo? " del Capítulo 12.

  

Siempre que implemente una colección reutilizable de comportamiento, tendrá que decidir si desea utilizar un rasgo o una clase abstracta. No existe una regla firme, pero esta sección contiene algunas pautas a tener en cuenta.

     

Si el comportamiento no se reutilizará, conviértalo en una clase concreta. No es un comportamiento reutilizable después de todo.

     

Si se puede reutilizar en varias clases no relacionadas, conviértalo en un rasgo. Solo los rasgos se pueden mezclar en diferentes partes de la jerarquía de clases.

Hay un poco más de información en el enlace anterior con respecto a los rasgos y le sugiero que lea la sección completa. Espero que esto ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top