Взяв следующий класс и интерфейс:
public class A {
public int foo() {
return 1;
}
}
public interface B {
default int foo() {
return 2;
}
}
Если вы определяете подкласс в java, как это
public class C extends A implements B {
}
Вызов foo для экземпляра C вернет 1, поскольку java предпочитает суперкласс интерфейсу.
Выполнение того же самого в scala дает ошибку компиляции:
class D extends A with B
Error:(3, 9) class D inherits conflicting members:
method foo in class A of type ()Int and
method foo in trait B of type ()Int
(Note: this can be resolved by declaring an override in class D.)
Ручное переопределение метода
class D extends A with B {
override def foo(): Int = super.foo()
}
Все еще дает неправильное поведение, вызов foo для экземпляра D вернет 2.
Чтобы в этом случае класс scala вел себя так же, как java, вы вручную переопределяете каждый метод и указываете A в качестве суперкласса в каждом вызове.
class D extends A with B {
override def foo(): Int = super[A].foo()
}
Почему так реализовано? И есть ли разумный способ обойти это, не переопределяя вручную каждый метод в этой ситуации?
public
, заменитьimplements
наwith
, добавитьdef
перед методами, изменить<>
на[]
и скомпилировать. Было бы запутанно, если бы интерфейсы, пришедшие из Java, рассматривались как совершенно другие понятия, чем трейты в Scala. - person Jasper-M   schedule 21.02.2017