scala 在抽象类上使用特征的优点是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1229743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the pros of using traits over abstract classes?
提问by Zack Marrapese
Can someone please explain traits in Scala? What are the advantages of traits over extending an abstract class?
有人可以解释Scala中的特征吗?与扩展抽象类相比,traits 有什么优势?
采纳答案by André Laszlo
The short answer is that you can use multiple traits -- they are "stackable". Also, traits cannot have constructor parameters.
简短的回答是您可以使用多个特征——它们是“可堆叠的”。此外,traits 不能有构造函数参数。
Here's how traits are stacked. Notice that the ordering of the traits are important. They will call each other from right to left.
以下是特征的堆叠方式。请注意,特征的顺序很重要。他们会从右到左互相呼唤。
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
}
}
回答by agilefall
This sitegives a good example of trait usage. One big advantage of traits is that you can extend multiple traits but only one abstract class. Traits solve many of the problems with multiple inheritance but allow code reuse.
该站点提供了一个很好的 trait 使用示例。特征的一大优点是您可以扩展多个特征,但只能扩展一个抽象类。Traits 解决了多重继承的许多问题,但允许代码重用。
If you know ruby, traits are similar to mix-ins
如果您了解 ruby,那么 trait 就类似于 mix-ins
回答by Mohan Narayanaswamy
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! )
回答by Serkan
This is the best example I've seen
这是我见过的最好的例子
Scala in practice: Composing Traits – Lego style: http://gleichmann.wordpress.com/2009/10/21/scala-in-practice-composing-traits-lego-style/
Scala 实践:编写特征 – 乐高风格: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
}
回答by Todd Flanders
Traits are useful for mixing functionality into a class. Take a look at http://scalatest.org/. Note how you can mix in various domain-specific languages (DSL) into a test class. look at the quick start guide to look at some of the DSL's supported by Scalatest ( http://scalatest.org/quick_start)
特征对于将功能混合到类中很有用。看看http://scalatest.org/。请注意如何将各种特定于域的语言 (DSL) 混合到测试类中。查看快速入门指南以了解 Scalatest 支持的一些 DSL ( http://scalatest.org/quick_start)
回答by Bao Luu
Similar to interfaces in Java, traits are used to define object types by specifying the signature of the supported methods.
与 Java 中的接口类似,特征用于通过指定支持方法的签名来定义对象类型。
Unlike Java, Scala allows traits to be partially implemented; i.e. it is possible to define default implementations for some methods.
与 Java 不同,Scala 允许部分实现特征;即可以为某些方法定义默认实现。
In contrast to classes, traits may not have constructor parameters. Traits are like classes, but which define an interface of functions and fields that classes can supply concrete values and implementations.
与类相反,特征可能没有构造函数参数。Traits 就像类,但它定义了一个函数和字段的接口,类可以提供具体的值和实现。
Traits can inherit from other traits or from classes.
特征可以从其他特征或类继承。
回答by consuela
I am quoting from the website of the book Programming in Scala, First Editionand more specifically the section called "To trait, or not to trait?" from Chapter 12.
我引用了《Scala 编程》第一版一书的网站,更具体地说,是第 12 章中名为“ To trait, or not to trait?”的部分。
Whenever you implement a reusable collection of behavior, you will have to decide whether you want to use a trait or an abstract class. There is no firm rule, but this section contains a few guidelines to consider.
If the behavior will not be reused, then make it a concrete class. It is not reusable behavior after all.
If it might be reused in multiple, unrelated classes, make it a trait. Only traits can be mixed into different parts of the class hierarchy.
每当您实现可重用的行为集合时,您都必须决定是要使用特征还是抽象类。没有固定的规则,但本节包含一些需要考虑的准则。
如果该行为不会被重用,则将其设为具体类。毕竟它不是可重用的行为。
如果它可能在多个不相关的类中重用,请将其设为 trait。只有特征可以混合到类层次结构的不同部分。
There is a bit more information in the above link regarding traits and I suggest you read the full section. I hope this helps.
上面的链接中有更多关于特征的信息,我建议您阅读完整部分。我希望这有帮助。

