Czy ktoś może wyjaśnić cechy w Scali? Jakie są zalety cech nad rozszerzeniem klasy abstrakcyjnej?
81
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
}
}
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
źródło
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) { }
źródło
To najlepszy przykład, jaki widziałem
Scala w praktyce: Cechy komponowania - styl 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 }
źródło
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 )
źródło
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.
źródło
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.
W powyższym linku jest trochę więcej informacji na temat cech i sugeruję przeczytanie całej sekcji. Mam nadzieję, że to pomoże.
źródło