В 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; работа метода имеет несовместимый тип".
Как выбрать один конкретный метод?
Ответы
Ответ 1
Я боюсь, что это невозможно. 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
Ответ 2
Вы не можете этого сделать.
Посмотрите на этот фрагмент кода:
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
}
}
Ответ 3
Scala просто мешает вам смешивать A
и B
вместе, если они объявляют метод с тем же именем и несовместимой сигнатурой.
Ответ 4
Вы не можете сделать это в 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
}