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

81

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

Зак Маррапез
источник

Ответы:

80

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

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

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
  }
}
Андре Ласло
источник
4
Отсутствие параметров конструктора почти компенсируется использованием параметров типа в трейтах.
Jus12,
19

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

Если вы знаете рубин, трейты похожи на примеси

проворство
источник
5
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) {
}
Вывод :

Список (я Рэй
, Я Рэй, это плохой день!
, Я Рэй, сегодня прекрасный день!
, Я Рэй, это плохой день!
, Я Рэй, сегодня прекрасный день!
)

Mohan
источник
3

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

Тодд Фландерс
источник
1

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

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

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

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

Бао Луу
источник
1

Я цитирую веб-сайт книги « Программирование на Scala, первое издание» и, в частности, раздел под названием « Для характеристики или не для характеристики? » Из главы 12.

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

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

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

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

Consuela
источник