What are the pros of using traits over abstract classes?

ScalaTraits

Scala Problem Overview


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

Scala Solutions


Solution 1 - Scala

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

Solution 2 - Scala

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

Solution 3 - Scala

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

Solution 4 - Scala

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
    }

Solution 5 - Scala

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 )

Solution 6 - 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.

Solution 7 - Scala

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionZack MarrapeseView Question on Stackoverflow
Solution 1 - ScalaAndré LaszloView Answer on Stackoverflow
Solution 2 - ScalaagilefallView Answer on Stackoverflow
Solution 3 - ScalaMohan NarayanaswamyView Answer on Stackoverflow
Solution 4 - ScalaSerkanView Answer on Stackoverflow
Solution 5 - ScalaTodd FlandersView Answer on Stackoverflow
Solution 6 - ScalaBao LuuView Answer on Stackoverflow
Solution 7 - ScalaconsuelaView Answer on Stackoverflow