How to choose in Scala which trait to choose implementation from in case of conflicting method signatures?
Suppose the following Java interfaces:
interface Dog {
default void makeSound() {
System.out.println("Woof");
}
default void beHappy() {
System.out.println("Wag tail");
}
}
interface Cat {
default void makeSound() {
System.out.println("Meow");
}
default void beHappy() {
System.out.println("Purrr");
}
}
And now suppose I want a purring dog, without reimplementing anything:
public class PurringDog implements Dog, Cat {
@Override
public void makeSound() {
Dog.super.makeSound();
}
@Override
public void beHappy() {
Cat.super.beHappy();
}
public static void main(String[] args) {
PurringDog purringDog = new PurringDog();
purringDog.makeSound(); //prints Woof
purringDog.beHappy(); //prints Purrr
}
}
How can this be achieved in Scala?
You can use super with a qualifier:
trait Dog {
def makeSound(): Unit = println("Woof")
def beHappy(): Unit = println("Wag tail")
}
trait Cat {
def makeSound(): Unit = println("Meow")
def beHappy(): Unit = println("Purrr")
}
class PurringDog extends Dog with Cat {
override def makeSound() = super[Dog].makeSound()
override def beHappy() = super[Cat].beHappy()
}
object Test extends App {
val purringDog = new PurringDog
purringDog.beHappy()
purringDog.makeSound()
}
Note that you can use the qualifier only for the traits you mix in directly (those appearing after an extends
or a with
), so crawling on the hierarchy (e.g. having a base trait Animal
) won't work with qualifiers.