与抽象类相比,使用特征有什么优点?

发布于 2024-07-30 14:43:59 字数 47 浏览 5 评论 0原文

有人可以解释一下 Scala 中的特征吗? 与扩展抽象类相比,特征有哪些优点?

Can someone please explain traits in Scala? What are the advantages of traits over extending an abstract class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

绅刃 2024-08-06 14:43:59

简而言之,您可以使用多个特征——它们是“可堆叠的”。 此外,特征不能有构造函数参数。

以下是特质的堆叠方式。 请注意,特征的顺序很重要。 他们会从右到左互相称呼。

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
  }
}

The short answer is that you can use multiple traits -- they are "stackable". Also, traits cannot have constructor parameters.

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
  }
}
十雾 2024-08-06 14:43:59

这个网站提供了一个很好的特征使用示例。 特征的一大优点是您可以扩展多个特征,但只能扩展一个抽象类。 特征解决了多重继承的许多问题,但允许代码重用。

如果你了解 ruby​​,trait 与 mix-ins 类似

This site gives 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.

If you know ruby, traits are similar to mix-ins

柠檬色的秋千 2024-08-06 14:43:59
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!
)

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

把回忆走一遍 2024-08-06 14:43:59

看到的 Scala 最好的例子

这是我在实践中 :Composition Traits – Lego style:
http://gleichmann.wordpress。 com/2009/10/21/scala-in-practice-composition-traits-lego-style/

    class Shuttle extends Spacecraft with ControlCabin with PulseEngine{

        val maxPulse = 10

        def increaseSpeed = speedUp
    }

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/

    class Shuttle extends Spacecraft with ControlCabin with PulseEngine{

        val maxPulse = 10

        def increaseSpeed = speedUp
    }
你与昨日 2024-08-06 14:43:59

特征对于将功能混合到类中非常有用。 看一下 http://scalatest.org/。 请注意如何将各种特定于域的语言 (DSL) 混合到测试类中。 查看快速入门指南,了解 Scalatest 支持的一些 DSL ( http://scalatest.org/quick_start)

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 )

温柔戏命师 2024-08-06 14:43:59

与 Java 中的接口类似,特征用于通过指定受支持方法的签名来定义对象类型。

与 Java 不同,Scala 允许部分实现特征; 即可以为某些方法定义默认实现。

与类相反,特征可能没有构造函数参数。
特征类似于类,但它定义了函数和字段的接口,类可以提供具体的值和实现。

特征可以从其他特征或类继承。

Similar to interfaces in Java, traits are used to define object types by specifying the signature of the supported methods.

Unlike Java, Scala allows traits to be partially implemented; i.e. it is possible to define default implementations for some methods.

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 can inherit from other traits or from classes.

旧时浪漫 2024-08-06 14:43:59

我引用了Programming in Scala, First Edition一书的网站,更具体地说,是“要特质,还是不要特质?"来自第 12 章。

每当您实现可重用的行为集合时,您都必须决定是要使用特征还是抽象类。 没有明确的规则,但本节包含一些需要考虑的准则。

如果该行为不会被重用,则将其设为具体类。 毕竟这不是可重用的行为。

如果它可以在多个不相关的类中重用,请将其设为特征。 只有特征可以混合到类层次结构的不同部分中。

上面的链接中有更多关于特征的信息,我建议您阅读完整部分。 我希望这有帮助。

I am quoting from the website of the book Programming in Scala, First Edition and more specifically the section called "To trait, or not to trait?" from Chapter 12.

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.

There is a bit more information in the above link regarding traits and I suggest you read the full section. I hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文