Каковы преимущества использования признаков над абстрактными классами?


может кто - нибудь объяснить черты в Scala? Каковы преимущества признаков перед расширением абстрактного класса?

7 78

7 ответов:

короткий ответ заключается в том, что вы можете использовать несколько черт-они являются "составной". Кроме того, черты не могут иметь параметры конструктора.

вот как складываются черты. Обратите внимание, что упорядочение признаков имеет важное значение. Они будут звонить друг другу справа налево.

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
  }
}

этой сайт дает хороший пример использования признака. Одним из больших преимуществ признаков является то, что вы можете расширить несколько признаков, но только один абстрактный класс. Черты решают многие проблемы с множественным наследованием, но позволяют повторно использовать код.

Если вы знаете ruby, черты похожи на миксы

Это лучший пример, который я видел

Scala на практике: составление черт-стиль 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
    }
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!
)

черты полезны для смешивания функциональности в классе. Взгляните на http://scalatest.org/. Обратите внимание, как вы можете смешивать различные доменные языки (DSL) в тестовом классе. посмотрите на краткое руководство, чтобы посмотреть на некоторые из DSL, поддерживаемых Scalatest ( http://scalatest.org/quick_start)

подобно интерфейсам в Java, признаки используются для определения типов объектов путем указания сигнатуры поддерживаемых методов.

В отличие от Java, Scala позволяет частично реализовать черты; т. е. можно определить реализации по умолчанию для некоторых методов.

В отличие от классов, черты характера могут не иметь параметров конструктора. Черты похожи на классы, но которые определяют интерфейс функций и полей, которые классы могут предоставлять конкретные значения и реализации.

черты могут наследовать от других черт или от классов.

я цитирую с сайта книги программирование в Scala, первое издание и более конкретно раздел под названием"к черту или не к черту?" из главы 12.

всякий раз, когда вы реализуете многоразовую коллекцию поведения, вам нужно будет решить, хотите ли вы использовать признак или абстрактный класс. Нет твердого правила, но этот раздел содержит несколько рекомендаций для рассмотрения.

Если поведение не будет повторно используется, а затем сделать его конкретным классом. В конце концов, это не многоразовое поведение.

Если он может быть повторно использован в нескольких несвязанных классов, сделать его черта. Только признаки могут быть смешаны в различных частях иерархии классов.

в приведенной выше ссылке есть немного больше информации о чертах, и я предлагаю вам прочитать полный раздел. Надеюсь, это поможет.