Ian Ian - 3 months ago 16
Scala Question

Stacking traits and abstract classes with overrides

Let's say I have the following code where I allow hybrid beings and because someone can mix and match species (e.g. just have pure humans or pure aliens), I'd like to have a method that explains what's been 'mixed in', which is called

say
:

trait Person {

def say(): Unit

}

trait Human {

def say(): Unit = println("Hi, I am a human")
}

trait Dude extends Human {

override def say(): Unit = {
super.say()
println("Duuude!")
}
}

abstract class Alien(msg: String) extends Person {

def say(): Unit = println(s"Hi, I'm an alien: $msg")
}

class Hybrid(name: String) extends Alien("bleep") with Dude // does not work!

val someone = new Hybrid("John")
someone.say()


This does not compile because:

error: overriding method say in class Alien of type ()Unit;
method say in trait Dude of type ()Unit cannot override a concrete member without a third member that's overridden by both (...)


Is it possible to have someone.say() display the following?

Hi, I'm am a human
Duuude!
Hi, I'm an alien: bleep


I have thought about creating a special class that already mixes in both traits/classes but how would I then go about accessing the respective
say
methods, as obviously
super.say
will be ambiguous.

Answer
class Hybrid(name: String) extends Alien("bleep") with Dude {
  override def say() = {
    super[Dude].say()
    super[Alien].say()
  }
}