有人可以解释Scala中的特征吗?特征优于扩展抽象类有什么优势?
答案 0 :(得分:79)
简短的回答是你可以使用多种特征 - 它们是“可堆叠的”。此外,traits不能有构造函数参数。
以下是特征的堆叠方式。请注意,特征的排序很重要。他们会从右到左互相打电话。
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
}
}
答案 1 :(得分:19)
这个site给出了特质使用的一个很好的例子。特征的一大优点是你可以扩展多个特征,但只能扩展一个抽象类。 Traits解决了多重继承的许多问题,但允许代码重用。
如果你知道红宝石,那么特质与混合相似
答案 2 :(得分: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) {
}
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! )
答案 3 :(得分:4)
这是我见过的最好的例子
实践中的斯卡拉:构成特征 - 乐高风格: 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
}
答案 4 :(得分:3)
特征对于将功能混合到类中非常有用。看看http://scalatest.org/。请注意如何将各种特定于域的语言(DSL)混合到测试类中。查看快速入门指南,了解Scalatest支持的一些DSL(http://scalatest.org/quick_start)
答案 5 :(得分:1)
与Java中的接口类似,traits用于通过指定支持的方法的签名来定义对象类型。
与Java不同,Scala允许部分实现特征;即,可以为某些方法定义默认实现。
与类相比,traits可能没有构造函数参数。 特征就像类,但它定义了一个函数和字段的接口,类可以提供具体的值和实现。
特征可以从其他特征或类继承。
答案 6 :(得分:1)
我引用了本书的网站 Scala编程,第一版,更具体地说是“#34; To trait, or not to trait?"来自第12章。
每当您实现可重用的行为集合时,您将必须决定是否要使用特征或抽象类。没有确定的规则,但本节包含一些需要考虑的指导原则。
如果不再使用该行为,则将其设为具体类。毕竟,这不是可重复使用的行为。
如果它可能在多个不相关的类中重用,那么将其作为特征。只有特征可以混合到类层次结构的不同部分。
上述链接中有关于特征的更多信息,我建议您阅读完整部分。我希望这会有所帮助。