Jakie są zalety używania cech zamiast klas abstrakcyjnych?

81

Czy ktoś może wyjaśnić cechy w Scali? Jakie są zalety cech nad rozszerzeniem klasy abstrakcyjnej?

Zack Marrapese
źródło

Odpowiedzi:

80

Krótka odpowiedź jest taka, że ​​możesz używać wielu cech - można je układać w stosy. Ponadto cechy nie mogą mieć parametrów konstruktora.

Oto, jak zestawia się cechy. Zauważ, że kolejność cech jest ważna. Będą nawoływać się od prawej do lewej.

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
  }
}
André Laszlo
źródło
4
Brak parametrów konstruktora jest prawie nadrobiony przy użyciu parametrów typu w cechach.
Jus12
19

Ta witryna daje dobry przykład użycia cechy. Dużą zaletą cech jest to, że można rozszerzyć wiele cech, ale tylko jedną klasę abstrakcyjną. Cechy rozwiązują wiele problemów związanych z dziedziczeniem wielokrotnym, ale umożliwiają ponowne wykorzystanie kodu.

Jeśli znasz rubin, cechy są podobne do miksów

agilefall
źródło
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) {
}
Wynik :

Lista (jestem Ray
Jestem Ray, to zły dzień!
Jestem Ray, to piękny dzień!
Jestem Ray, to zły dzień!
Jestem Ray, to piękny dzień!
)

Mohana
źródło
3

Cechy są przydatne do mieszania funkcji w klasę. Spójrz na http://scalatest.org/ . Zwróć uwagę, jak możesz mieszać różne języki specyficzne dla domeny (DSL) w klasie testowej. spójrz na przewodnik szybkiego startu, aby zapoznać się z niektórymi DSL obsługiwanymi przez Scalatest ( http://scalatest.org/quick_start )

Todd Flanders
źródło
1

Podobnie jak w przypadku interfejsów w Javie, cechy służą do definiowania typów obiektów poprzez określenie podpisu obsługiwanych metod.

W przeciwieństwie do Javy, Scala umożliwia częściowe zaimplementowanie cech; tzn. możliwe jest zdefiniowanie domyślnych implementacji niektórych metod.

W przeciwieństwie do klas cechy mogą nie mieć parametrów konstruktora. Cechy są podobne do klas, ale definiują interfejs funkcji i pól, które klasy mogą dostarczać konkretnych wartości i implementacji.

Cechy mogą dziedziczyć z innych cech lub z klas.

Bao Luu
źródło
1

Cytuję ze strony internetowej książki Programming in Scala, First Edition, a dokładniej z sekcji „ To trait czy not to trait? ” Z rozdziału 12.

Za każdym razem, gdy implementujesz kolekcję zachowań wielokrotnego użytku, będziesz musiał zdecydować, czy chcesz użyć cechy, czy klasy abstrakcyjnej. Nie ma sztywnej reguły, ale ta sekcja zawiera kilka wskazówek do rozważenia.

Jeśli zachowanie nie zostanie ponownie użyte, utwórz z niego konkretną klasę. W końcu nie jest to zachowanie wielokrotnego użytku.

Jeśli może być ponownie użyty w wielu niepowiązanych ze sobą klasach, niech będzie cechą. Tylko cechy mogą być mieszane w różnych częściach hierarchii klas.

W powyższym linku jest trochę więcej informacji na temat cech i sugeruję przeczytanie całej sekcji. Mam nadzieję, że to pomoże.

consuela
źródło