В множественном наследовании scala, как разрешить конфликтующие методы с той же сигнатурой, но другим типом возврата?
рассмотрим код ниже:
trait A {
def work = { "x" }
}
trait B {
def work = { 1 }
}
class C extends A with B {
override def work = super[A].work
}
класс C
не будет компилироваться в scala 2.10 из-за"переопределения работы метода в черте A типа => String; работа метода имеет несовместимый тип".
Как выбрать один конкретный метод?
4 ответов
боюсь, что это невозможно сделать. The super[A].work
способ работает только если A
и B
имеют те же типы возврата.
рассмотрим следующий пример:
class D extends B
....
val test: List[B] = List(new C(), new D())
test.map(b => b.work) //oops - C returns a String, D returns an Int
Scala просто предотвращает вас от смешивания A
и B
вместе, если они объявляют метод с тем же именем и несовместимой подписью.
вы не можете этого сделать.
посмотрите на этот кусок кода:
val c = new C
val a: A = c
val b: B = c
это невозможно и из этих строк может работать:
val s: String = a.work
val i: Int = b.work
если бы мы позволили такому коду скомпилироваться, одно из этих назначений должно было бы бросить ClassCastException
или не по-другому. Таким образом, разрешить такой конфликт просто невозможно.
Я думаю, вам нужно обойти это с какой-то формой делегирования, может быть, что-то вроде этого:
class C extends A {
def toB = new B {
//implement B methods by somehow delegating them to C instance
}
}
вы не можете сделать это в Scala.
способ обойти это-использовать черты в качестве сотрудников
trait A {
def work = { "x" }
}
trait B {
def work = { 1 }
}
class C {
val a = new A { }
val b = new B { }
a.work
b.work
}