1

In my venture to learning Scala, I created the following hierarchy:

trait Animal {
  val name: String = "Animal"
}

trait HasLegs {
  this: Animal =>
  val numLegs: Int
}

abstract class Terrestrial extends Animal with HasLegs {
  val name: String = "Terrestrial"
}

class Dog(val name: String) extends Terrestrial {
  def numLegs = 4

  override def toString = {
    f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
  }
}

However, the compiler complains that in Dog.toString "super may be not be used on value name". What am I doing wrong?

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219

1 Answers1

3

There were a couple of issues, primarily stemming from using val in superclasses, which locks it down to a value, rather than something that can be overridden and accessed via super. There were also some problems with not specifying override:

trait Animal {
  // in order for super to be called on this it has to be a def
  def name: String = "Animal"
}

trait HasLegs {
  this: Animal =>
  val numLegs: Int
}

abstract class Terrestrial extends Animal with HasLegs {

  // this needs to be an override of Animal.name
  override def name: String = "Terrestrial"
}

class Dog(override val name: String) extends Terrestrial {

  // since the trait specified this as a val, the implementation
  // also needs to be a val
  val numLegs = 4

  override def toString = {
    f"My name is: $name%s. I'm a Dog and I've $numLegs%d legs. I'm from the ${super.name}%s family."
  }
}

I've commented on changes inline.

As for the reason why super cannot be used on val see SI-899

This is the intended behavior, and it was changed so that traits could override vals to be more uniform with classes.

Arne Claassen
  • 14,088
  • 5
  • 67
  • 106
  • So here the name from Terrestrial will be invoked. Is there a way to get the name from the Animal? Or does super work for immediate superclass only? – Abhijit Sarkar May 10 '15 at 02:11
  • See Jon Skeet's answer on why there is no super.super (he talks about Java but the same holds true for scala http://stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java – Arne Claassen May 10 '15 at 02:19