Scala Language Solving the Diamond Problem


Example

The diamond problem, or multiple inheritance, is handled by Scala using Traits, which are similar to Java interfaces. Traits are more flexible than interfaces and can include implemented methods. This makes traits similar to mixins in other languages.

Scala does not support inheritance from multiple classes, but a user can extend multiple traits in a single class:

trait traitA {
  def name = println("This is the 'grandparent' trait.")
}

trait traitB extends traitA {
  override def name = {
    println("B is a child of A.")
    super.name
  }

}

trait traitC extends traitA {
  override def name = {
    println("C is a child of A.")
    super.name
  }
}

object grandChild extends traitB with traitC

grandChild.name

Here grandChild is inheriting from both traitB and traitC, which in turn both inherit from traitA. The output (below) also shows the order of precedence when resolving which method implementations are called first:

C is a child of A. 
B is a child of A. 
This is the 'grandparent' trait.

Note that, when super is used to invoke methods in class or trait, linearization rule come into play to decide call hierarchy. Linearization order for grandChild will be:

grandChild -> traitC -> traitB -> traitA -> AnyRef -> Any


Below is another example:

trait Printer {
  def print(msg : String) = println (msg)
}

trait DelimitWithHyphen extends Printer {
  override def print(msg : String) {
    println("-------------")
    super.print(msg)
  }
}

trait DelimitWithStar extends Printer  {
  override def print(msg : String) {
    println("*************")
    super.print(msg)
  }
}

class CustomPrinter extends Printer with DelimitWithHyphen with DelimitWithStar

object TestPrinter{
  def main(args: Array[String]) {
    new CustomPrinter().print("Hello World!")
  }
}

This program prints:

*************
-------------
Hello World!

Linearization for CustomPrinter will be:

CustomPrinter -> DelimitWithStar -> DelimitWithHyphen -> Printer -> AnyRef -> Any