В Scala мне нужно переопределить следующие данные классы и методы Java:
public abstract class AbstractJava<T> {
protected abstract T test(Class<? extends T> clazz);
}
public class ConcreteJava extends AbstractJava<Object> {
@Override
protected Object test(Class<?> clazz) {
return null;
}
}
// Scala
class ConcreteScala extends ConcreteJava {
protected override def test(clazz: Class[_ <: AnyRef]): AnyRef =
super.test(clazz)
}
Я получаю ошибку компиляции:
error: ambiguous reference to overloaded definition,
both method test in class ConcreteJava of type
(clazz: java.lang.Class[_])java.lang.Object
and method test in class AbstractJava of type
(clazz: java.lang.Class[_ <: java.lang.Object])java.lang.Object
match argument types (Class[_$1]) and expected result type AnyRef
super.test(clazz)
Я бы не ожидал, что компилятор Scala будет ссылаться на метод abstract
при вызове super
. Кроме того, я ожидаю, что сначала он будет ссылаться на суперкласс direct .
Как я могу сделать компиляцию класса Scala?
Спасибо!
Edit:
При прекращении вызова super.test(clazz)
появится сообщение об ошибке:
error: name clash between defined and inherited member:
method test:(clazz: Class[_ <: AnyRef])AnyRef and
method test:(clazz: java.lang.Class[_])java.lang.Object in class ConcreteJava
have same type after erasure: (clazz: java.lang.Class)java.lang.Object
protected override def test(clazz: Class[_ <: AnyRef]): AnyRef = null
Ну, конечно это те же типы (или варианты) ...! - Что-то не так с наследованием Scala / Java ...
Благодаря michid , есть предварительное решение:
class ConcreteScala3 {
this: ConcreteJava =>
protected override def test(clazz: Class[_ <: AnyRef]): AnyRef = {
this.foo() // method of ConcreteJava
null
}
}
хотя мы не можем делать super
звонки отсюда.
Ответы по-прежнему приветствуются.