In the question you did not mention that Object doSomething(Class<?> clazz) method is the implementation of abstract T doSomething(Class<? extends T> clazz) method of abstract generic class.
So actually you have following Java classes (I renamed doSomething to test for brevity):
public abstract class AbstractJava<T> {
protected abstract T test(Class<? extends T> c);
}
public class ConcreteJava extends AbstractJava<Object> {
@Override
protected Object test(Class<?> c) {
return null;
}
}
And you are trying to implement following Scala class:
class ConcreteScala extends ConcreteJava {
override protected def test(c: Class[_]) = super.test(c)
}
But compilation fails because when you try to override test() Scala treats ConcreteJava.test() and AbstractJava.test() methods as if they have different signature.
I found the following workaround.
Create additional Java class that by overriding test() "renames" it to renameTest() and also provides ability to call super ConcreteJava.test() through concreteTest() method.
public abstract class RenameJava extends ConcreteJava {
public Object concreteTest(Class<?> c) {
return super.test(c);
}
abstract protected Object renameTest(Class<?> c);
@Override
protected Object test(Class<?> c) {
return renameTest(c);
}
}
Now in ConcreteScala class you can override renameTest() and you're still able to call super ConcreteJava.test() method using concreteTest() method.
class ConcreteScala extends RenameJava {
override protected def renameTest(c: Class[_]) = {
// custom logic
concreteTest(c)
}
}
In your specific "Spring" case it's implemented in the following way.
RenameGsonHttpMessageConverter.java
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import java.io.IOException;
public abstract class RenameGsonHttpMessageConverter extends GsonHttpMessageConverter {
protected Object superReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException {
return super.readInternal(clazz, inputMessage);
}
abstract protected Object renameReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException;
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return renameReadInternal(clazz, inputMessage);
}
}
CustomGsonHttpMessageConverter.scala
import org.springframework.http.HttpInputMessage
class CustomGsonHttpMessageConverter extends RenameGsonHttpMessageConverter {
override protected def renameReadInternal(clazz: Class[_], inputMessage: HttpInputMessage) = {
// custom logic
// or you may want to call
superReadInternal(clazz, inputMessage)
}
}
Also I made a bug report SI-10155.
override def doSomething(clazz: Class[_]): AnyRef = ???compiles fine with Scala 2.11.8 and JDK 8u91public class Base { protected Object doSomething(Class<?> clazz) { ... } }in a Java file, compiled it, then put it on the REPL classpath. Then I typedclass Sub extends Base { override def doSomething(clazz: Class[_]): AnyRef = ??? }, and it compiled fine. Same Scala/Java versions.