0

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.

Ian
  • 1,294
  • 3
  • 17
  • 39
  • 3
    You have conflicting methods in your implementation. What you want to achieve is absolutely doable but you have to introduce better inheritance model since the one that you have now simply does not compose. You could go with Alexey's answer which will do what you want but it does not resolve the poor structure. – sebszyller Sep 01 '16 at 09:45
  • duplicates http://stackoverflow.com/q/17500342/1296806 – som-snytt Sep 01 '16 at 09:57

2 Answers2

6
class Hybrid(name: String) extends Alien("bleep") with Dude {
  override def say() = {
    super[Dude].say()
    super[Alien].say()
  }
}
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
0

So Basically the class Hybrid doesnt know which say method needs to be overridden. This could be resolved by changing the method name . U can try this

trait Person {

  def say(): String

 }

  trait Human {
  def sayHuman: String = ("Hi, I am a human")
 }

trait Dude extends Human {

 override def sayHuman(): String = {
super.sayHuman +"Duuude!"
 }
}

 abstract class Alien(msg: String) extends Person {

  def say(): String= "Hi, I'm an alien:"+msg
}


class Hybrid(name: String) extends Alien("bleep") with Dude{
override def toString:String= super.say+"\n"+super.sayHuman
}
Rakshith
  • 644
  • 1
  • 8
  • 24