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

StackOverflow https://stackoverflow.com/questions/1229743

  •  22-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

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, черты похожи на дополнения

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

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

Scala на практике: составление черт & # 8211; Лего стиль: http: //gleichmann.wordpress. ком / 2009/10/21 / Scala-в-практике, сочиняя-черты лего-стиль /

    class Shuttle extends Spacecraft with ControlCabin with PulseEngine{

        val maxPulse = 10

        def increaseSpeed = speedUp
    }

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

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

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

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

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

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

  

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

     

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

     

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top